<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<![endif]-->
<title>VIM 中文帮助: 插入模式和替换模式</title>
<link rel="stylesheet" href="vim-stylesheet.css" type="text/css" />
<link rel="canonical" href="https://yianwillis.github.io/vimcdoc/doc/insert.html" />
<script type="text/javascript" src="vimcdoc.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<nav id=banner>
<form action=tags.html target="tag_iframe">
  <input type="text" name="tag" id="tag" placeholder="标签搜索">
</form>
<iframe name="tag_iframe" src=""></iframe>
<a href="help.html">帮助总览</a> &middot;
<hr/>
<a href="quickref.html">快速参考</a> &middot;
<a href="index.html">命令索引</a> &middot;
<a href="eval.html#functions">函数列表</a> &middot;
<a href="quickref.html#option-list">选项列表</a> &middot;
<hr/>
<a href="usr_toc.html">用户手册</a> &middot;
<a href="help.html#reference_toc">参考手册</a> &middot;
</nav>

<header>
<h2>insert</h2>
</header>
<article id=outer>
<section class=inner>
<b class="vimtag"> <a name="insert.txt">insert.txt</a> </b>    适用于 Vim 9.0 版本。   最近更新: 2023年2月


                  <code class="vim">VIM 参考手册    by Bram Moolenaar</code>
                                <code class="vim">译者</code>: Willis、tocer


                                                <b class="vimtag"> <a name="Insert">Insert</a> </b> <b class="vimtag"> <a name="Insert-mode">Insert-mode</a> </b>
插入和替换文本                                  <b class="vimtag"> <a name="mode-ins-repl">mode-ins-repl</a> </b>

本文件主要讨论插入和替换模式。最后讨论一些其它方式插入文本的命令。

最常用的命令的总览可以在用户手册第 24 章  <a href="usr_24.html#usr_24.txt">usr_24.txt</a>  找到。

1. 特殊键                                                <a href="insert.html#ins-special-keys">ins-special-keys</a> 
2. 特殊的特殊键                                          <a href="insert.html#ins-special-special">ins-special-special</a> 
3. <a href="options.html#'textwidth'">'textwidth'</a> 和 <a href="options.html#'wrapmargin'">'wrapmargin'</a> 选项                      <a href="insert.html#ins-textwidth">ins-textwidth</a> 
4. <a href="options.html#'expandtab'">'expandtab'</a>、<a href="options.html#'smarttab'">'smarttab'</a> 和 <a href="options.html#'softtabstop'">'softtabstop'</a>  选项        <a href="insert.html#ins-expandtab">ins-expandtab</a> 
5. 替换模式                                              <a href="insert.html#Replace-mode">Replace-mode</a> 
6. 虚拟替换模式                                          <a href="insert.html#Virtual-Replace-mode">Virtual-Replace-mode</a> 
7. 插入模式补全                                          <a href="insert.html#ins-completion">ins-completion</a> 
8. 插入模式命令                                          <a href="insert.html#inserting">inserting</a> 
9. Ex 插入命令                                           <a href="insert.html#inserting-ex">inserting-ex</a> 
10. 插入文件                                             <a href="insert.html#inserting-file">inserting-file</a> 

关于如何移动光标到没有字符的位置，另见 <a href="options.html#'virtualedit'">'virtualedit'</a>。对编辑表格有用。

</section><hr class="doubleline" /><section class=inner>
<h4>1. 特殊键                                               <b class="vimtag"> <a name="ins-special-keys">ins-special-keys</a> </b></h4>
在插入和替换模式里，以下字符有特殊含义；其它字符被直接插入。要插入这些特殊字符
到缓冲区里，在前面加上 <code class="keystroke">CTRL-V</code>。要插入 <code class="special">&lt;Nul&gt;</code> 字符，使用 "<code class="keystroke">CTRL-V</code> <code class="keystroke">CTRL-@</code>" 或者
"<code class="keystroke">CTRL-V</code> 000"。在有的系统上，你必须使用 "<code class="keystroke">CTRL-V</code> 003" 来插入 <code class="keystroke">CTRL-C</code>。<code class="note">注意</code>: 如果
<code class="keystroke">CTRL-V</code> 被映射，你也许会经常使用 <code class="keystroke">CTRL-Q</code> 来代替  <a href="insert.html#i_CTRL-Q">i_CTRL-Q</a> 。

如果插入时你在特殊的语言模式下工作，参见 <a href="options.html#'langmap'">'langmap'</a> 选项  <a href="options.html#'langmap'">'langmap'</a>  了解如何避
免反复进出这些模式。

如果置位了 <a href="options.html#'insertmode'">'insertmode'</a>，<code class="special">&lt;Esc&gt;</code> 和一些其它的键有另外的含义。见  <a href="options.html#'insertmode'">'insertmode'</a> 。

<code class="section">字符            动作    </code>
</section><hr class="singleline" /><section class=inner>
                                                <b class="vimtag"> <a name="i_CTRL-[">i_CTRL-[</a> </b> <b class="vimtag"> <a name="i_%3CEsc%3E">i_&lt;Esc&gt;</a> </b>
<code class="special">&lt;Esc&gt;</code> 或 <code class="keystroke">CTRL-[</code> 结束插入或替换模式，回到普通模式。结束缩写。
                <code class="note">注意</code>: 如果你很难在键盘上敲上 <code class="special">&lt;Esc&gt;</code> 键，训练自己使用 <code class="keystroke">CTRL-[</code>。
                如果 Esc 不能用而你使用的是 Mac，试试 <code class="keystroke">CTRL-Esc</code>。或者在辅助功能
                里关闭收听。
                                                <b class="vimtag"> <a name="i_CTRL-C">i_CTRL-C</a> </b>
<code class="keystroke">CTRL-C</code>          退出插入模式，回到普通模式。不检查缩写。不激活  <a href="autocmd.html#InsertLeave">InsertLeave</a> 
                自动命令事件。

                                                <b class="vimtag"> <a name="i_CTRL-@">i_CTRL-@</a> </b>
<code class="keystroke">CTRL-@</code>          插入最近插入的文本，并停止插入。
                                                <b class="vimtag"> <a name="i_CTRL-A">i_CTRL-A</a> </b>
<code class="keystroke">CTRL-A</code>          插入最近插入的文本。

                                                <b class="vimtag"> <a name="i_CTRL-H">i_CTRL-H</a> </b> <b class="vimtag"> <a name="i_%3CBS%3E">i_&lt;BS&gt;</a> </b> <b class="vimtag"> <a name="i_BS">i_BS</a> </b>
<code class="special">&lt;BS&gt;</code> 或 <code class="keystroke">CTRL-H</code>  删除光标前的字符 (关于连接行，见  <a href="insert.html#i_backspacing">i_backspacing</a> )。
                如果你的 <code class="special">&lt;BS&gt;</code> 键不正确，见  <a href="options.html#:fixdel">:fixdel</a> 。
                                                <b class="vimtag"> <a name="i_%3CDel%3E">i_&lt;Del&gt;</a> </b> <b class="vimtag"> <a name="i_DEL">i_DEL</a> </b>
<code class="special">&lt;Del&gt;</code>           删除光标下的字符。如果光标在行尾，并且 <a href="options.html#'backspace'">'backspace'</a> 选项包括
                "eol"，删除 <code class="special">&lt;EOL&gt;</code>；下一行就此附加于当前行之后。
                如果你的 <code class="special">&lt;Del&gt;</code> 键不正确，见  <a href="options.html#:fixdel">:fixdel</a> 。
                                                <b class="vimtag"> <a name="i_CTRL-W">i_CTRL-W</a> </b>
<code class="keystroke">CTRL-W</code>          删除光标前的单词 (关于连接行，见  <a href="insert.html#i_backspacing">i_backspacing</a> )。关于单词的
                定义，见  <a href="motion.html#word-motions">word-motions</a>  关于 "单词动作" 的定义。
                                                <b class="vimtag"> <a name="i_CTRL-U">i_CTRL-U</a> </b>
<code class="keystroke">CTRL-U</code>          删除当前行上光标前的所有输入字符。如果没有新输入的字符而
                <a href="options.html#'backspace'">'backspace'</a> 不为空，删除当前行上光标前的所有字符。
                打开 C-缩进时，如果行被清空，调整缩进。
                关于连接行，见  <a href="insert.html#i_backspacing">i_backspacing</a> 。
                                                <b class="vimtag"> <a name="i_CTRL-I">i_CTRL-I</a> </b> <b class="vimtag"> <a name="i_%3CTab%3E">i_&lt;Tab&gt;</a> </b> <b class="vimtag"> <a name="i_Tab">i_Tab</a> </b>
<code class="special">&lt;Tab&gt;</code> 或 <code class="keystroke">CTRL-I</code> 插入制表。如果打开 <a href="options.html#'expandtab'">'expandtab'</a> 选项，等价数目的空格被插入 (使
                用 <code class="keystroke">CTRL-V</code> <code class="special">&lt;Tab&gt;</code> 避免这种扩展: 如果 <code class="keystroke">CTRL-V</code> 被映射，可以使用
                <code class="keystroke">CTRL-Q</code> <code class="special">&lt;Tab&gt;</code>。 <a href="insert.html#i_CTRL-Q">i_CTRL-Q</a> )。另见 <a href="options.html#'smarttab'">'smarttab'</a> 选项和
                 <a href="insert.html#ins-expandtab">ins-expandtab</a> 。
                                                <b class="vimtag"> <a name="i_CTRL-J">i_CTRL-J</a> </b> <b class="vimtag"> <a name="i_%3CNL%3E">i_&lt;NL&gt;</a> </b>
<code class="special">&lt;NL&gt;</code> 或 <code class="keystroke">CTRL-J</code>  开始新行。
                                                <b class="vimtag"> <a name="i_CTRL-M">i_CTRL-M</a> </b> <b class="vimtag"> <a name="i_%3CCR%3E">i_&lt;CR&gt;</a> </b>
<code class="special">&lt;CR&gt;</code> 或 <code class="keystroke">CTRL-M</code>  开始新行。
                                                <b class="vimtag"> <a name="i_CTRL-K">i_CTRL-K</a> </b>
<code class="keystroke">CTRL-K</code> <code class="special">{char1}</code> <code class="special">[char2]</code>
                输入二合字母 (见  <a href="digraph.html#digraphs">digraphs</a> )。当 <code class="special">{char1}</code> 为特殊字符时，该键的
                键码以 <code class="special">&lt;&gt;</code> 形式插入。例如字符串 "<code class="special">&lt;S-Space&gt;</code>" 可以这样输入:
                <code class="special">&lt;C-K&gt;</code><code class="special">&lt;S-Space&gt;</code> (两个键)。两个键都不考虑映射。

<code class="keystroke">CTRL-N</code>          查找下一个关键字 (见  <a href="insert.html#i_CTRL-N">i_CTRL-N</a> )。
<code class="keystroke">CTRL-P</code>          查找上一个关键字 (见  <a href="insert.html#i_CTRL-P">i_CTRL-P</a> )。

<code class="keystroke">CTRL-R</code> <code class="special">{register}</code>                               <b class="vimtag"> <a name="i_CTRL-R">i_CTRL-R</a> </b>
                插入寄存器内容。在输入 <code class="keystroke">CTRL-R</code> 和第二个字符之间，'"' 会显示出
                来，以提示你需要输入寄存器的名字。文本插入方式和直接输入相同，
                但不使用映射和缩写。如果设置了 <a href="options.html#'textwidth'">'textwidth'</a>、<a href="options.html#'formatoptions'">'formatoptions'</a> 或
                <a href="options.html#'autoindent'">'autoindent'</a>，插入的结果会受到影响。这和使用 "p" 命令和用鼠标
                粘贴文本不同。
                特殊寄存器:
                        '"'     无名寄存器，包含最近删除或抽出的文本
                        '%'     当前文件名
                        '#'     轮换文件名
                        '*'     剪贴板内容 (X11: 主选择)
                        '+'     剪贴板内容
                        '/'     最近的搜索模式
                        ':'     最近的命令行
                        '.'     最近插入的文本
                        '-'     最近的行内 (少于一行) 删除
                                                        <b class="vimtag"> <a name="i_CTRL-R_%20">i_CTRL-R_=</a> </b>
                        '='     表达式寄存器；你会被提示输入一个表达式 (见
                                 <a href="eval.html#expression">expression</a> )
                                <code class="note">注意</code> 0x80 (十进制 128) 用于特殊键。例如，你可
                                以这样移动光标向上:
                                        <code class="keystroke">CTRL-R</code> ="\<code class="special">&lt;Up&gt;</code>"
                                用 <code class="keystroke">CTRL-R</code> <code class="keystroke">CTRL-R</code> 可以按本义插入文本。
                                如果结果是  <a href="eval.html#List">List</a> ，里面的项目被看作行，之间以
                                换行符连接。
                                如果结果是浮点数，自动转化为字符串。
                                调用 append() 或 setline() 会打断撤销序列。
                关于寄存器见  <a href="change.html#registers">registers</a> 。

<code class="keystroke">CTRL-R</code> <code class="keystroke">CTRL-R</code> <code class="special">{register}</code>                        <b class="vimtag"> <a name="i_CTRL-R_CTRL-R">i_CTRL-R_CTRL-R</a> </b>
                插入寄存器内容。和单个 <code class="keystroke">CTRL-R</code> 类似，但是文本按本义插入，而不是
                像键盘输入那样。这意味着如果寄存器包含 <code class="special">&lt;BS&gt;</code> 这样的字符，结果会
                不同。例如，如果寄存器包含 "ab^Hc": 
<code class="example">        CTRL-R a                产生 "ac"。</code>
<code class="example">        CTRL-R CTRL-R a         产生 "ab^Hc"。</code>
                <a href="options.html#'textwidth'">'textwidth'</a>、<a href="options.html#'formatoptions'">'formatoptions'</a> 等等选项仍然适用。如果你连这些都
                想避免，使用 <code class="keystroke">CTRL-R</code> <code class="keystroke">CTRL-O</code>，见下。
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                此命令后，'.' 寄存器包含该寄存器的文本，如同键盘输入那样的方式
                插入。

<code class="keystroke">CTRL-R</code> <code class="keystroke">CTRL-O</code> <code class="special">{register}</code>                        <b class="vimtag"> <a name="i_CTRL-R_CTRL-O">i_CTRL-R_CTRL-O</a> </b>
                按本义插入寄存器内容，并且不进行自动缩进。和鼠标粘贴文本相同
                 <a href="change.html#%3CMiddleMouse%3E">&lt;MiddleMouse&gt;</a> 。如果寄存器是面向行的，在当前行之上插入文本，
                类似于 P。
                不会替换字符！
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                此命令后，'.' 寄存器包含键入的命令而不是文本，也就是本义值
                "^R^O" 而不是寄存器的文本。

<code class="keystroke">CTRL-R</code> <code class="keystroke">CTRL-P</code> <code class="special">{register}</code>                        <b class="vimtag"> <a name="i_CTRL-R_CTRL-P">i_CTRL-R_CTRL-P</a> </b>
                按本义插入寄存器内容，修正缩进，和  <a href="change.html#[%3CMiddleMouse%3E">[&lt;MiddleMouse&gt;</a>  类似。
                不会替换字符！
                '.' 寄存器 (最近插入的文本) 依然如同键盘输入那样的方式插入。
                此命令后，'.' 寄存器包含键入的命令而不是文本，也就是本义值
                "^R^P" 而不是寄存器的文本。

                                                <b class="vimtag"> <a name="i_CTRL-T">i_CTRL-T</a> </b>
<code class="keystroke">CTRL-T</code>          在当前行开始处插入一个 shiftwidth 的缩进。缩进总是取整到
                <a href="options.html#'shiftwidth'">'shiftwidth'</a> 的倍数 (这是 vi 兼容的)。
                                                <b class="vimtag"> <a name="i_CTRL-D">i_CTRL-D</a> </b>
<code class="keystroke">CTRL-D</code>          在当前行开始处删除一个 shiftwidth 的缩进。缩进总是取整到
                <a href="options.html#'shiftwidth'">'shiftwidth'</a> 的倍数 (这是 vi 兼容的)。
                                                <b class="vimtag"> <a name="i_0_CTRL-D">i_0_CTRL-D</a> </b>
0 <code class="keystroke">CTRL-D</code>        删除所有当前行的缩进。
                                                <b class="vimtag"> <a name="i_^_CTRL-D">i_^_CTRL-D</a> </b>
^ <code class="keystroke">CTRL-D</code>        删除当前行的所有缩进。缩进在下一行上恢复。这可以用于插入卷标。

                                                <b class="vimtag"> <a name="i_CTRL-V">i_CTRL-V</a> </b>
<code class="keystroke">CTRL-V</code>          如果下一个是非数字，按本义插入。对特殊键而言，插入其终端代码。
                不然，输入的是字符的十、八或十六进制值。 <a href="insert.html#i_CTRL-V_digit">i_CTRL-V_digit</a> 。
                <code class="keystroke">CTRL-V</code> 之后紧接着输入的字符不经过映射。
                <code class="note">注意</code>: 当 <code class="keystroke">CTRL-V</code> 被映射时 (例如，用来粘贴文本)，你可能经常需要
                使用 <code class="keystroke">CTRL-Q</code> 来代替  <a href="insert.html#i_CTRL-Q">i_CTRL-Q</a> 。
                如果打开  <a href="map.html#modifyOtherKeys">modifyOtherKeys</a> ，特殊转义序列被转换回没有
                 <a href="map.html#modifyOtherKeys">modifyOtherKeys</a>  时的样子，除非同时按住 Shift 键。

                                                <b class="vimtag"> <a name="i_CTRL-Q">i_CTRL-Q</a> </b>
<code class="keystroke">CTRL-Q</code>          同 <code class="keystroke">CTRL-V</code>。
                <code class="note">注意</code>: 有的终端连接会吃掉 <code class="keystroke">CTRL-Q</code>，导致该快捷键无效。在 GUI 版本
                里就不会出现这样的问题。

<code class="keystroke">CTRL-SHIFT</code>-V                            <b class="vimtag"> <a name="i_CTRL-SHIFT-V">i_CTRL-SHIFT-V</a> </b> <b class="vimtag"> <a name="i_CTRL-SHIFT-Q">i_CTRL-SHIFT-Q</a> </b>
<code class="keystroke">CTRL-SHIFT</code>-Q    与 <code class="keystroke">CTRL-V</code> 类似，除非激活了  <a href="map.html#modifyOtherKeys">modifyOtherKeys</a> ，此时插入带修饰符
                的键的转义序列。

<code class="keystroke">CTRL-X</code>          进入 <code class="keystroke">CTRL-X</code> 模式，一个子模式。那里你可以给出命令来补全单词或者
                滚动窗口。见  <a href="insert.html#i_CTRL-X">i_CTRL-X</a>  和  <a href="insert.html#ins-completion">ins-completion</a> 。

                                                <b class="vimtag"> <a name="i_CTRL-E">i_CTRL-E</a> </b>
<code class="keystroke">CTRL-E</code>          插入光标下面的字符。
                                                <b class="vimtag"> <a name="i_CTRL-Y">i_CTRL-Y</a> </b>
<code class="keystroke">CTRL-Y</code>          插入光标上面的字符。
                <code class="note">注意</code> <code class="keystroke">CTRL-E</code> 和 <code class="keystroke">CTRL-Y</code> 不使用 <a href="options.html#'textwidth'">'textwidth'</a>，从而可以从长行里复制
                字符。

                                                <b class="vimtag"> <a name="i_CTRL-_">i_CTRL-_</a> </b>
<code class="keystroke">CTRL-_</code>          切换语言，如下:
                -  在从右到左的窗口里，切换 revins 和 nohkmap，因为在这种情况
                   下英语的输入可能就是倒过来的。
                -  在非从右到左的窗口里，切换 revins 和 hkmap。因为希伯来语等
                   语种可能是倒过来输入的。

                <code class="keystroke">CTRL-_</code> 移动光标到输入文本的尾部。

                该命令只有在 <a href="options.html#'allowrevins'">'allowrevins'</a> 选项置位的时候才有效。
                请参考  <a href="rileft.html#rileft.txt">rileft.txt</a> ，那里可以了解到更多有关从右到左模式的信
                息。
                只有在编译时加入  <a href="various.html#+rightleft">+rightleft</a>  特性才有效。

                                                <b class="vimtag"> <a name="i_CTRL-^">i_CTRL-^</a> </b>
<code class="keystroke">CTRL-^</code>          切换语言字符输入的使用方式。
                如果定义了语言映射  <a href="map.html#:lmap">:lmap</a> :
                - <a href="options.html#'iminsert'">'iminsert'</a> 为 1 (使用 langmap 映射) 时变成 0 (不使用 langmap
                  映射)。
                - <a href="options.html#'iminsert'">'iminsert'</a> 为其它值时变成 1，从而打开 langmap 映射。
                如果没有定义语言映射:
                - <a href="options.html#'iminsert'">'iminsert'</a> 为 2 (使用输入方法 (Input Method)) 时变成 0 (不使
                  用输入方法)。
                - <a href="options.html#'iminsert'">'iminsert'</a> 为其它值时变成 2，从而打开输入方法。
                如果 为 1，"b:keymap_name" 变量的值、<a href="options.html#'keymap'">'keymap'</a> 选项或者
                "<code class="special">&lt;lang&gt;</code>" 出现在状态行上。
                这些语言映射通常用来输入键盘上不能直接产生的字符。<a href="options.html#'keymap'">'keymap'</a> 选
                项用来安装若干完整的这样的映射表。

                                                <b class="vimtag"> <a name="i_CTRL-]">i_CTRL-]</a> </b>
<code class="keystroke">CTRL-]</code>          触发缩写，不插入字符。

                                                <b class="vimtag"> <a name="i_%3CInsert%3E">i_&lt;Insert&gt;</a> </b>
<code class="special">&lt;Insert&gt;</code>        在插入和替换模式间切换。
</section><hr class="singleline" /><section class=inner>

                                                <b class="vimtag"> <a name="i_backspacing">i_backspacing</a> </b>
<code class="special">&lt;BS&gt;</code>、<code class="keystroke">CTRL-W</code> 和 <code class="keystroke">CTRL-U</code> 的效果决定于 <a href="options.html#'backspace'">'backspace'</a> 选项 (除非置位了 <a href="options.html#'revins'">'revins'</a>)。这
时一个逗号分隔的项目列表:

<code class="section">项目        动作 </code>
indent      允许退格删除自动缩进
eol         允许退格删除换行符 (连接行)
start       允许退格删除插入开始之前的位置；<code class="keystroke">CTRL-W</code> 和 <code class="keystroke">CTRL-U</code> 在开始位置停止

如果 <a href="options.html#'backspace'">'backspace'</a> 为空，则使用 Vi 兼容的退格方式。不能退格删除自动缩进、回到第
一列之前、或者超过插入开始的地方。

为了后向兼容起见，取值 "0"、"1"、"2" 和 "3" 也是允许的，见  <a href="options.html#'backspace'">'backspace'</a> 。

如果 <a href="options.html#'backspace'">'backspace'</a> 选项的确包含 "eol"，光标在第一列，而使用了这三个键中的一个，
当前行会和上一行连接。这实际上删除了光标之前的 <code class="special">&lt;EOL&gt;</code>。

                                                <b class="vimtag"> <a name="i_CTRL-V_digit">i_CTRL-V_digit</a> </b>
使用 <code class="keystroke">CTRL-V</code>，可以通过十、八、十六进制值来直接输入字符。这样你可以输入除了换行
符 (<code class="special">&lt;NL&gt;</code>，其值为 10) 以外的任何字符。有五种输入字符值的方法:

<code class="section">首个字符        模式           最大字符数       最大值 </code>
(无)            十进制             3            255
o 或 O          八进制             3            377      (255)
x 或 X          十六进制           2            ff       (255)
u               十六进制           4            ffff     (65535)
U               十六进制           8            7fffffff (2147483647)

通常你要输入最大数目的字符数。要输入空格 (值为 32) 的时候需要键入 <code class="special">&lt;C-V&gt;</code>032。开
头的零可以忽略，但此时数字之后的字符必须不能再是数字。其它模式也一样: 一旦输入
了在该模式下不合法的字符，那么这之前的值就会被使用，而 "非法" 的这个字符会以正
常的方式继续处理。

输入的值为 10 时，在文件中最后会以 0 出现。10 是 <code class="special">&lt;NL&gt;</code>，内部它被用来代表 <code class="special">&lt;Nul&gt;</code>
字符。而写入文件时，<code class="special">&lt;NL&gt;</code> 字符被翻译成 <code class="special">&lt;Nul&gt;</code>。每行的最后会写入 <code class="special">&lt;NL&gt;</code>。所以，如果
你确实想在文件中插入 <code class="special">&lt;NL&gt;</code> 字符，请使用换行。
另见 <a href="options.html#'fileformat'">'fileformat'</a>。

                                                <b class="vimtag"> <a name="i_CTRL-X">i_CTRL-X</a> </b> <b class="vimtag"> <a name="insert_expand">insert_expand</a> </b>
<code class="keystroke">CTRL-X</code> 进入一个子模式，那里可以使用若干命令。绝大多数命令执行关键字补全；见
 <a href="insert.html#ins-completion">ins-completion</a> 。

有两个命令可以在不退出插入模式的前提下上下滚动窗口:

                                                <b class="vimtag"> <a name="i_CTRL-X_CTRL-E">i_CTRL-X_CTRL-E</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-E</code>           窗口滚动上移一行。
                        补全时看这里:  <a href="insert.html#complete_CTRL-E">complete_CTRL-E</a> 

                                                <b class="vimtag"> <a name="i_CTRL-X_CTRL-Y">i_CTRL-X_CTRL-Y</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-Y</code>           窗口滚动下移一行。
                        补全时看这里:  <a href="insert.html#complete_CTRL-Y">complete_CTRL-Y</a> 

按了 <code class="keystroke">CTRL-X</code> 以后，每个 <code class="keystroke">CTRL-E</code> (<code class="keystroke">CTRL-Y</code>) 滚动窗口上 (下) 移一行，除非这使得光标
不得不离开当前文件中所在的位置。一旦按了另外一个键，<code class="keystroke">CTRL-X</code> 模式就会退出，而回
到插入模式下解释该键。


</section><hr class="doubleline" /><section class=inner>
<h4>2. 特殊的特殊键                                 <b class="vimtag"> <a name="ins-special-special">ins-special-special</a> </b></h4>
以下的键是特殊的。它们停止当前的插入，做一些事情，然后重新插入。这意味着你可以
不脱离插入模式的情况下做一些事情。这适合于经常使用插入模式的用户，就像编辑器没
有单独的普通模式一样。也可以考虑设置 <a href="options.html#'backspace'">'backspace'</a> 选项为 "indent,eol,start" 还
有置位 <a href="options.html#'insertmode'">'insertmode'</a> 选项。如果你想把功能键映射到命令上，可以使用 <code class="keystroke">CTRL-O</code>。

可以分别撤销这些键之前和之后的改动 (字符的插入或者删除)。只有最后的改动可以重
做，这和 "i" 命令的行为相当。

<code class="section">字符            动作    </code>
</section><hr class="singleline" /><section class=inner>
<code class="special">&lt;Up&gt;</code>            光标上移一行                                 <b class="vimtag"> <a name="i_%3CUp%3E">i_&lt;Up&gt;</a> </b>
<code class="special">&lt;Down&gt;</code>          光标下移一行                                 <b class="vimtag"> <a name="i_%3CDown%3E">i_&lt;Down&gt;</a> </b>
<code class="keystroke">CTRL-G</code> <code class="special">&lt;Up&gt;</code>     光标上移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_%3CUp%3E">i_CTRL-G_&lt;Up&gt;</a> </b>
<code class="keystroke">CTRL-G</code> k        光标上移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_k">i_CTRL-G_k</a> </b>
<code class="keystroke">CTRL-G</code> <code class="keystroke">CTRL-K</code>   光标上移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_CTRL-K">i_CTRL-G_CTRL-K</a> </b>
<code class="keystroke">CTRL-G</code> <code class="special">&lt;Down&gt;</code>   光标下移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_%3CDown%3E">i_CTRL-G_&lt;Down&gt;</a> </b>
<code class="keystroke">CTRL-G</code> j        光标下移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_j">i_CTRL-G_j</a> </b>
<code class="keystroke">CTRL-G</code> <code class="keystroke">CTRL-J</code>   光标下移一行，到插入开始时所在的列           <b class="vimtag"> <a name="i_CTRL-G_CTRL-J">i_CTRL-G_CTRL-J</a> </b>
<code class="special">&lt;Left&gt;</code>          光标左移一个字符                             <b class="vimtag"> <a name="i_%3CLeft%3E">i_&lt;Left&gt;</a> </b>
<code class="special">&lt;Right&gt;</code>         光标右移一个字符                             <b class="vimtag"> <a name="i_%3CRight%3E">i_&lt;Right&gt;</a> </b>
<code class="special">&lt;S-Left&gt;</code>        光标反向一个单词 (类同 "b" 命令)             <b class="vimtag"> <a name="i_%3CS-Left%3E">i_&lt;S-Left&gt;</a> </b>
<code class="special">&lt;C-Left&gt;</code>        光标反向一个单词 (类同 "b" 命令)             <b class="vimtag"> <a name="i_%3CC-Left%3E">i_&lt;C-Left&gt;</a> </b>
<code class="special">&lt;S-Right&gt;</code>       光标正向一个单词 (类同 "w" 命令)             <b class="vimtag"> <a name="i_%3CS-Right%3E">i_&lt;S-Right&gt;</a> </b>
<code class="special">&lt;C-Right&gt;</code>       光标正向一个单词 (类同 "w" 命令)             <b class="vimtag"> <a name="i_%3CC-Right%3E">i_&lt;C-Right&gt;</a> </b>
<code class="special">&lt;Home&gt;</code>          光标移到该行首个字符                         <b class="vimtag"> <a name="i_%3CHome%3E">i_&lt;Home&gt;</a> </b>
<code class="special">&lt;End&gt;</code>           光标移到该行末个字符之后                     <b class="vimtag"> <a name="i_%3CEnd%3E">i_&lt;End&gt;</a> </b>
<code class="special">&lt;C-Home&gt;</code>        光标移到该文件首个字符                       <b class="vimtag"> <a name="i_%3CC-Home%3E">i_&lt;C-Home&gt;</a> </b>
<code class="special">&lt;C-End&gt;</code>         光标移到该文件末个字符之后                   <b class="vimtag"> <a name="i_%3CC-End%3E">i_&lt;C-End&gt;</a> </b>
<code class="special">&lt;LeftMouse&gt;</code>     光标移动鼠标点击处                           <b class="vimtag"> <a name="i_%3CLeftMouse%3E">i_&lt;LeftMouse&gt;</a> </b>
<code class="special">&lt;S-Up&gt;</code>          上翻窗口一页                                 <b class="vimtag"> <a name="i_%3CS-Up%3E">i_&lt;S-Up&gt;</a> </b>
<code class="special">&lt;PageUp&gt;</code>        上翻窗口一页                                 <b class="vimtag"> <a name="i_%3CPageUp%3E">i_&lt;PageUp&gt;</a> </b>
<code class="special">&lt;S-Down&gt;</code>        下翻窗口一页                                 <b class="vimtag"> <a name="i_%3CS-Down%3E">i_&lt;S-Down&gt;</a> </b>
<code class="special">&lt;PageDown&gt;</code>      下翻窗口一页                                 <b class="vimtag"> <a name="i_%3CPageDown%3E">i_&lt;PageDown&gt;</a> </b>
<code class="special">&lt;ScrollWheelDown&gt;</code>    窗口向下滚动三行                   <b class="vimtag"> <a name="i_%3CScrollWheelDown%3E">i_&lt;ScrollWheelDown&gt;</a> </b>
<code class="special">&lt;S-ScrollWheelDown&gt;</code>  窗口向下滚动一个整页               <b class="vimtag"> <a name="i_%3CS-ScrollWheelDown%3E">i_&lt;S-ScrollWheelDown&gt;</a> </b>
<code class="special">&lt;ScrollWheelUp&gt;</code>      窗口向上滚动三行                   <b class="vimtag"> <a name="i_%3CScrollWheelUp%3E">i_&lt;ScrollWheelUp&gt;</a> </b>
<code class="special">&lt;S-ScrollWheelUp&gt;</code>    窗口向上滚动一个整页               <b class="vimtag"> <a name="i_%3CS-ScrollWheelUp%3E">i_&lt;S-ScrollWheelUp&gt;</a> </b>
<code class="special">&lt;ScrollWheelLeft&gt;</code>    窗口向左滚动六列                   <b class="vimtag"> <a name="i_%3CScrollWheelLeft%3E">i_&lt;ScrollWheelLeft&gt;</a> </b>
<code class="special">&lt;S-ScrollWheelLeft&gt;</code>  窗口向左滚动一个整页               <b class="vimtag"> <a name="i_%3CS-ScrollWheelLeft%3E">i_&lt;S-ScrollWheelLeft&gt;</a> </b>
<code class="special">&lt;ScrollWheelRight&gt;</code>   窗口向右滚动六列                   <b class="vimtag"> <a name="i_%3CScrollWheelRight%3E">i_&lt;ScrollWheelRight&gt;</a> </b>
<code class="special">&lt;S-ScrollWheelRight&gt;</code> 窗口向右滚动一个整页               <b class="vimtag"> <a name="i_%3CS-ScrollWheelRight%3E">i_&lt;S-ScrollWheelRight&gt;</a> </b>
<code class="keystroke">CTRL-O</code>          执行命令，然后返回到插入模式                 <b class="vimtag"> <a name="i_CTRL-O">i_CTRL-O</a> </b>
<code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-O</code>   类似于 <code class="keystroke">CTRL-O</code>，但不移动光标                  <b class="vimtag"> <a name="i_CTRL-\_CTRL-O">i_CTRL-\_CTRL-O</a> </b>
<code class="keystroke">CTRL-L</code>          置位 <a href="options.html#'insertmode'">'insertmode'</a> 时: 转到普通模式           <b class="vimtag"> <a name="i_CTRL-L">i_CTRL-L</a> </b>
<code class="keystroke">CTRL-G</code> u        结束撤销序列，开始新的改变                   <b class="vimtag"> <a name="i_CTRL-G_u">i_CTRL-G_u</a> </b>
<code class="keystroke">CTRL-G</code> U        只要光标停在同一行，下个左/右光标移动不新起  <b class="vimtag"> <a name="i_CTRL-G_U">i_CTRL-G_U</a> </b>
                撤销块
</section><hr class="singleline" /><section class=inner>

<code class="note">备注</code>: 如果光标键把你带出了插入模式，查查 <a href="options.html#'noesckeys'">'noesckeys'</a> 选项。

<code class="keystroke">CTRL-O</code> 命令有时有副作用: 如果光标在行尾之外，它会先被移动该行最后一个字符上。
在映射里，通常更好的方法是使用 <code class="special">&lt;Esc&gt;</code> (先在文本中放一个 "x"，<code class="special">&lt;Esc&gt;</code> 这时总会把光
标放到它的上面)。或者使用 <code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-O</code>，不过这时要<code class="note">注意</code>光标可能移到行尾之外的
位置。<code class="note">注意</code> <code class="keystroke">CTRL-\</code> <code class="keystroke">CTRL-O</code> 后跟的命令仍然可以移动光标，光标不会自动恢复到原来的
位置。

<code class="keystroke">CTRL-O</code> 命令带你到普通模式，此时如使用了进入插入模式的命令，插入模式通常不会嵌
套。因而，输入完 "a<code class="special">&lt;C-O&gt;</code>a" 然后按 <code class="special">&lt;Esc&gt;</code>，你会立即回到普通模式，不需要按 <code class="special">&lt;Esc&gt;</code>
两次。一个例外是此命令如果不是直接键入而是在比如执行映射或执行脚本时，嵌套仍然
会发生。只有这样，短暂切换到插入模式的映射才可以工作。

不是在所有的终端上都能用 Shift + 光标键。

另外一个副作用是 "i" 或 "a" 命令之前指定的计数会被忽略。这是因为要实现 <code class="keystroke">CTRL-O</code>
之后的命令的重复执行太复杂了。

一个使用 <code class="keystroke">CTRL-G</code> u 的例子: 
<code class="example"></code>
<code class="example">        :inoremap &lt;C-H&gt; &lt;C-G&gt;u&lt;C-H&gt;</code>
<code class="example"></code>
它重定义退格键使之开始新的撤销序列。现在可以用 <code class="keystroke">CTRL-O</code> u 来撤销退格键的效果，而
不会改变你之前输入的内容。另一例: 
<code class="example"></code>
<code class="example">        :inoremap &lt;CR&gt; &lt;C-]&gt;&lt;C-G&gt;u&lt;CR&gt;</code>
<code class="example"></code>
这样，每行之后都会开始新的撤销块。在此之前也扩展缩写。

一个使用 <code class="keystroke">CTRL-G</code> U 的例子: 
<code class="example"></code>
<code class="example">        inoremap &lt;Left&gt;  &lt;C-G&gt;U&lt;Left&gt;</code>
<code class="example">        inoremap &lt;Right&gt; &lt;C-G&gt;U&lt;Right&gt;</code>
<code class="example">        inoremap &lt;expr&gt; &lt;Home&gt; col('.') == match(getline('.'), '\S') + 1 ?</code>
<code class="example">         \ repeat('&lt;C-G&gt;U&lt;Left&gt;', col('.') - 1) :</code>
<code class="example">         \ (col('.') &lt; match(getline('.'), '\S') ?</code>
<code class="example">         \     repeat('&lt;C-G&gt;U&lt;Right&gt;', match(getline('.'), '\S') + 0) :</code>
<code class="example">         \     repeat('&lt;C-G&gt;U&lt;Left&gt;', col('.') - 1 - match(getline('.'), '\S')))</code>
<code class="example">        inoremap &lt;expr&gt; &lt;End&gt; repeat('&lt;C-G&gt;U&lt;Right&gt;', col('$') - col('.'))</code>
<code class="example">        inoremap ( ()&lt;c-g&gt;u&lt;left&gt;</code>
<code class="example"></code>
这样，插入模式下使用光标键就不会开始新的撤销块，. (重做) 命令因此才会正常工
作。还有，输入以下的文本 (使用上述的 "(" 映射):

   Lorem ipsum (dolor

就可以用  <a href="repeat.html#.">.</a>  重做，以出现以下的期待结果

   Lorem ipsum (dolor)

<code class="keystroke">CTRL-O</code> 的使用分割撤销: 之前和之后的输入的文本被分别撤销。如果不想如此 (比如用
在映射里)，可能可用 <code class="keystroke">CTRL-R</code> =  <a href="insert.html#i_CTRL-R">i_CTRL-R</a> 。例如，要调用函数: 
<code class="example">        :imap &lt;F2&gt; &lt;C-R&gt;=MyFunc()&lt;CR&gt;</code>
<code class="example"></code>
正确设置 <a href="options.html#'whichwrap'">'whichwrap'</a> 选项的话，在一行的首个/末个字符上按 <code class="special">&lt;Left&gt;</code> 和 <code class="special">&lt;Right&gt;</code> 键
会使光标回绕到上一行/下一行。

<code class="keystroke">CTRL-G</code> j 和 <code class="keystroke">CTRL-G</code> k 命令可用来在同一列前插入文本。例如: 
<code class="example">   int i;</code>
<code class="example">   int j;</code>
把光标定位在第一个 "int" 上，输入 "istatic <code class="special">&lt;C-G&gt;</code>j       "。结果是: 
<code class="example">   static int i;</code>
<code class="example">          int j;</code>
要在每行的同一列之前插入相同的文本，可用可视列块命令 "I"  <a href="visual.html#v_b_I">v_b_I</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>3. <a href="options.html#'textwidth'">'textwidth'</a> 和 <a href="options.html#'wrapmargin'">'wrapmargin'</a> 选项                     <b class="vimtag"> <a name="ins-textwidth">ins-textwidth</a> </b></h4>
<a href="options.html#'textwidth'">'textwidth'</a> 选项可以用来在行变得很长之前自动断行。设置 <a href="options.html#'textwidth'">'textwidth'</a> 选项为希望
的最大行长。如果你输入更多字符 (不是空格或者制表)，最后一个单词会放在一个新行
上 (除非这是该行唯一一个单词)。如果你设置 <a href="options.html#'textwidth'">'textwidth'</a> 为 0，该特性被关闭。

<a href="options.html#'wrapmargin'">'wrapmargin'</a> 选项做的事情基本相同。区别在于 <a href="options.html#'textwidth'">'textwidth'</a> 是一个固定的宽度，而
<a href="options.html#'wrapmargin'">'wrapmargin'</a> 根据屏幕的宽度设置。设置 <a href="options.html#'wrapmargin'">'wrapmargin'</a> 等价于 <a href="options.html#'textwidth'">'textwidth'</a> 设为
(columns - <a href="options.html#'wrapmargin'">'wrapmargin'</a>)，其中 columns 是屏幕的宽度。

如果同时设置 <a href="options.html#'textwidth'">'textwidth'</a> 和 <a href="options.html#'wrapmargin'">'wrapmargin'</a>，使用 <a href="options.html#'textwidth'">'textwidth'</a>。

如果你并不真的想断开行，而只是想文本行在合适的位置回绕，见 <a href="options.html#'linebreak'">'linebreak'</a> 选项。

文本行只有在插入模式下或者附加到行后的时候才会自动断开。在替换模式下，只要行的
长度没有变，就不会断行。

长行在你输入一个出现在边界之后的非空白字符的时候断开。在 <a href="options.html#'formatoptions'">'formatoptions'</a> 选项
里加入如下字母可以限制断行的时机:
"l"  只有当插入开始时文本行的长度不超过 <a href="options.html#'textwidth'">'textwidth'</a>，断行才会发生。
"v"  只在当前插入命令中输入的一个空白字符上断行。这是和 Vi 最兼容的行为。
"lv" 只有当插入开始时文本行的长度不超过 <a href="options.html#'textwidth'">'textwidth'</a>，并且在当前插入命令中输入
     的一个空白字符上断行才会发生。和 "l" 唯一的不同在于跨越 <a href="options.html#'textwidth'">'textwidth'</a> 边界
     时输入的都是非空白字符的时候。

通常使用内部函数来决定在哪里断行。如果你想用不同的方法，设置 <a href="options.html#'formatexpr'">'formatexpr'</a> 选项
为处理换行的表达式。

如果想排版文本块，可用 "gq" 操作符。输入 "gq" 紧跟一个移动光标到块尾的移动命
令。在许多情况下，命令 "gq}" 会做你想要做的事情 (排版直到段落尾部)。也可用
"gqap" 来排版整个段落而不管光标当前在哪个位置。也可用可视模式: 敲击 "v"，移动
到块尾，然后输入 "gq"。另见  <a href="change.html#gq">gq</a> 。

</section><hr class="doubleline" /><section class=inner>
<h4>4. <a href="options.html#'expandtab'">'expandtab'</a>、<a href="options.html#'smarttab'">'smarttab'</a> 和 <a href="options.html#'softtabstop'">'softtabstop'</a> 选项        <b class="vimtag"> <a name="ins-expandtab">ins-expandtab</a> </b></h4>
如果打开 <a href="options.html#'expandtab'">'expandtab'</a> 选项，空格可以用来填充制表键的空白位置。如果你需要输入真
正的 <code class="special">&lt;Tab&gt;</code>，先输入 <code class="keystroke">CTRL-V</code> (如果 <code class="keystroke">CTRL-V</code> 被映射的话可用 <code class="keystroke">CTRL-Q</code>  <a href="insert.html#i_CTRL-Q">i_CTRL-Q</a> ) 再
做。
缺省关闭 <a href="options.html#'expandtab'">'expandtab'</a> 选项。<code class="note">注意</code> 替换模式下，一个字符会被多个空格字符所代替。结
果是行内的字符数会增加。退格键一次删一个空格键。只有一个空格 (最后一个) 上的退
格才能得回原来的字符。

                                                        <b class="vimtag"> <a name="ins-smarttab">ins-smarttab</a> </b>
打开 <a href="options.html#'smarttab'">'smarttab'</a> 选项时，<code class="special">&lt;Tab&gt;</code> 在行首插入 <a href="options.html#'shiftwidth'">'shiftwidth'</a> 个位置，而在其它地方插
入 <a href="options.html#'tabstop'">'tabstop'</a> 个位置。这意味着插入的常常是空格而不是 <code class="special">&lt;Tab&gt;</code> 字符。而关闭
<a href="options.html#'smarttab'">'smarttab'</a> 时，<code class="special">&lt;Tab&gt;</code> 总是插入 <a href="options.html#'tabstop'">'tabstop'</a> 个位置，只有在 "&gt;&gt;" 和类似命令中才会用
到 <a href="options.html#'shiftwidth'">'shiftwidth'</a>。

                                                        <b class="vimtag"> <a name="ins-softtabstop">ins-softtabstop</a> </b>
如果 <a href="options.html#'softtabstop'">'softtabstop'</a> 选项不为零，<code class="special">&lt;Tab&gt;</code> 插入 <a href="options.html#'softtabstop'">'softtabstop'</a> 个位置，而过去用来删除
空格的 <code class="special">&lt;BS&gt;</code>，现在会删除 <a href="options.html#'softtabstop'">'softtabstop'</a> 个位置。感觉上，<a href="options.html#'tabstop'">'tabstop'</a> 被设成了
<a href="options.html#'softtabstop'">'softtabstop'</a> 的值，但实际上一个真正的 <code class="special">&lt;Tab&gt;</code> 字符还是占据 <a href="options.html#'tabstop'">'tabstop'</a> 个位置。从
而，你的文件在别的应用程序里看起来还是正确的。

如果 <a href="options.html#'softtabstop'">'softtabstop'</a> 不为零，<code class="special">&lt;BS&gt;</code> 会试图删除尽量多的空白，以便能够回到往前
<a href="options.html#'softtabstop'">'softtabstop'</a> 的位置，除非前面一个插入的字符正好就是一个空格，这时它只会删除光
标前的那个字符。否则，你不一定总能删除光标前的一个字符。你将不得不先删除
<a href="options.html#'softtabstop'">'softtabstop'</a> 个字符，然后再输入额外的空格，以到达你想要的地方。

</section><hr class="doubleline" /><section class=inner>
<h4>5. 替换模式                             <b class="vimtag"> <a name="Replace">Replace</a> </b> <b class="vimtag"> <a name="Replace-mode">Replace-mode</a> </b> <b class="vimtag"> <a name="mode-replace">mode-replace</a> </b></h4>
普通模式下输入 "R" 命令进入替换模式。

替换模式下，输入的每个字符会删除行内的一个字符。如果没有字符可以删了 (在行
尾)，则附加输入的字符 (此时和插入模式一样)。这样，直到到达行尾前，行内的字符数
保持不变。如果输入的是 <code class="special">&lt;NL&gt;</code>，插入换行符，但不会删除任何字符。

要小心 <code class="special">&lt;Tab&gt;</code> 字符。如果在其上输入一个正常的可显示字符，字符数仍然一样，但是列
数看起来少了。

如果你在替换模式下删除字符 (用 <code class="special">&lt;BS&gt;</code>、<code class="keystroke">CTRL-W</code> 或 <code class="keystroke">CTRL-U</code>)，实际发生的事是你删除了
改变。被替换的字符被复原了。如果你的输入超过已有的部分，新增的字符会被删除。实
际上，这可以看作是一次一个字符的撤销。

如果打开了 <a href="options.html#'expandtab'">'expandtab'</a> 选项，<code class="special">&lt;Tab&gt;</code> 会用多个空格替换一个字符。结果是行内的字符
数会增加。退格键只能一次删一个空格。只有一个空格 (最后一个) 上的退格才能得回原
来的字符。

</section><hr class="doubleline" /><section class=inner>
<h4>6. 虚拟替换模式                         <b class="vimtag"> <a name="vreplace-mode">vreplace-mode</a> </b> <b class="vimtag"> <a name="Virtual-Replace-mode">Virtual-Replace-mode</a> </b></h4>
在普通模式里输入 "gR" 命令进入虚拟替换模式。
<code class="notvi">{仅当编译时加入  <a href="various.html#+vreplace">+vreplace</a>  特性才会有效}</code>

虚拟替换模式和替换模式类似，但不是替换文件里的实际字符，而是替换屏幕的领地。这
样，文件里的字符看起来不会移动。

所以，如果你输入了 <code class="special">&lt;Tab&gt;</code>，它会替换多个普通的字符，而如果你在 <code class="special">&lt;Tab&gt;</code> 上输入字
母，它可能什么都没有代替，因为 <code class="special">&lt;Tab&gt;</code> 还是会占据相同的位置。

输入 <code class="special">&lt;NL&gt;</code> 还是不会导致文件后面的字符看起来移动过。当前行的后面部分被 <code class="special">&lt;NL&gt;</code>
所替换 (也就是，它们被删除了)，而替换继续在下一行进行。 <code class="emphasis">不</code> 会插入新行，除非
你到达文件尾部之后。

输入 <code class="keystroke">CTRL-T</code> 和 <code class="keystroke">CTRL-D</code> 会看到有趣的效果。光标前面的字符跟平常一样向一边移动，但
是光标后面的字符保持不动。<code class="keystroke">CTRL-T</code> 会隐藏被移动字符遮盖的部分旧行，而 <code class="keystroke">CTRL-D</code> 会
重新让它们显现出来。

和替换模式一样，使用 <code class="special">&lt;BS&gt;</code> 等会恢复被替换的字符。即使和 <a href="options.html#'smartindent'">'smartindent'</a>、<code class="keystroke">CTRL-T</code>
和 <code class="keystroke">CTRL-D</code>、<a href="options.html#'expandtab'">'expandtab'</a>、<a href="options.html#'smarttab'">'smarttab'</a>、<a href="options.html#'softtabstop'">'softtabstop'</a> 等一起使用的效果也是如此。

在 <a href="options.html#'list'">'list'</a> 模式下，虚拟替换模式的行为和不在 <a href="options.html#'list'">'list'</a> 模式下一样，除非 <a href="options.html#'cpoptions'">'cpoptions'</a>
里设置了 "L"。

<code class="note">注意</code> 在此模式下，光标之后的字符看起来在移动的情况仅有列表模式  <a href="options.html#'list'">'list'</a> ，置位
<a href="options.html#'wrap'">'wrap'</a> 时偶尔也会出现 (当行改变了长度，使得比屏幕宽度更窄或者更宽时)。其他情况
下空格会被插入，以防止之后的字符移动。

该模式对编辑 <code class="special">&lt;Tab&gt;</code> 分隔表格列的时候很有用，因为输入新的数据时同时还能保持所有
的列对齐。

</section><hr class="doubleline" /><section class=inner>
<h4>7. 插入模式补全                                         <b class="vimtag"> <a name="ins-completion">ins-completion</a> </b></h4>
在插入和替换模式下，有若干命令可以补全输入的部分关键字或者行。这可以用于使用复
杂关键字的场合 (例如，函数名里有大写字母或者下划线)。

补全可以是针对:

1. 整行                                                  <a href="insert.html#i_CTRL-X_CTRL-L">i_CTRL-X_CTRL-L</a> 
2. 当前文件内的关键字                                    <a href="insert.html#i_CTRL-X_CTRL-N">i_CTRL-X_CTRL-N</a> 
3. <a href="options.html#'dictionary'">'dictionary'</a> 的关键字                                 <a href="insert.html#i_CTRL-X_CTRL-K">i_CTRL-X_CTRL-K</a> 
4. <a href="options.html#'thesaurus'">'thesaurus'</a> 的关键字，同义词风格                      <a href="insert.html#i_CTRL-X_CTRL-T">i_CTRL-X_CTRL-T</a> 
5. 当前文件及其头文件内的关键字                          <a href="insert.html#i_CTRL-X_CTRL-I">i_CTRL-X_CTRL-I</a> 
6. 标签                                                  <a href="insert.html#i_CTRL-X_CTRL-]">i_CTRL-X_CTRL-]</a> 
7. 文件名                                                <a href="insert.html#i_CTRL-X_CTRL-F">i_CTRL-X_CTRL-F</a> 
8. 定义或宏                                              <a href="insert.html#i_CTRL-X_CTRL-D">i_CTRL-X_CTRL-D</a> 
9. Vim 命令                                              <a href="insert.html#i_CTRL-X_CTRL-V">i_CTRL-X_CTRL-V</a> 
10. 用户定义的补全                                       <a href="insert.html#i_CTRL-X_CTRL-U">i_CTRL-X_CTRL-U</a> 
11. 全能 (omni) 补全                                     <a href="insert.html#i_CTRL-X_CTRL-O">i_CTRL-X_CTRL-O</a> 
12. 拼写建议                                             <a href="insert.html#i_CTRL-X_s">i_CTRL-X_s</a> 
13. <a href="options.html#'complete'">'complete'</a> 的关键字                                  <a href="insert.html#i_CTRL-N">i_CTRL-N</a>   <a href="insert.html#i_CTRL-P">i_CTRL-P</a> 

此外， <a href="insert.html#i_CTRL-X_CTRL-Z">i_CTRL-X_CTRL-Z</a>  停止补全而不改动现有的文本。

除了 <code class="keystroke">CTRL-N</code> 和 <code class="keystroke">CTRL-P</code> 以外，所有这些都通过 <code class="keystroke">CTRL-X</code> 模式完成。这是插入和替换模式
的一个子模式。你可以键入 <code class="keystroke">CTRL-X</code> 后跟一个 <code class="keystroke">CTRL-X</code> 命令来进入 <code class="keystroke">CTRL-X</code> 模式。要退出
<code class="keystroke">CTRL-X</code> 模式，输入非合法的 <code class="keystroke">CTRL-X</code> 模式命令就行了。合法的键包括 <code class="keystroke">CTRL-X</code> 命令自
身， <code class="keystroke">CTRL-N</code> (后一个) 和 <code class="keystroke">CTRL-P</code> (前一个)。

想得到当前补全的信息，可用  <a href="builtin.html#complete_info()">complete_info()</a> 。
如果你想调整匹配的大小写，另见 <a href="options.html#'infercase'">'infercase'</a> 选项。

                                                        <b class="vimtag"> <a name="complete_CTRL-E">complete_CTRL-E</a> </b>
如果补全处于激活状态，可以用 <code class="keystroke">CTRL-E</code> 来停止补全并回到原来录入的文字。<code class="keystroke">CTRL-E</code> 本
身不会被插入。

                                                        <b class="vimtag"> <a name="complete_CTRL-Y">complete_CTRL-Y</a> </b>
如果显示了弹出菜单，可以使用 <code class="keystroke">CTRL-Y</code> 停止补全并接受当前的选择项。<code class="keystroke">CTRL-Y</code> 本身不
会被插入。键入空格、回车或者其他不可显示字符将离开补全模式并插入键入的字符。

显示弹出菜单时，有一些特殊键可用，见  <a href="insert.html#popupmenu-keys">popupmenu-keys</a> 。

<code class="note">注意</code>: <code class="keystroke">CTRL-X</code> 模式下合法的键不经过映射。这使得 `:map <code class="special">&lt;C-F&gt;</code> <code class="special">&lt;C-X&gt;</code><code class="special">&lt;C-F&gt;</code>` 能够工作
(假定 <a href="options.html#'cpo'">'cpo'</a> 里不含 "&lt;")。能够使得 <code class="keystroke">CTRL-X</code> 模式退出的键 (任何不是合法 <code class="keystroke">CTRL-X</code> 模
式命令的键) 则经过映射。另外，通过 <a href="options.html#'complete'">'complete'</a> 的补全也应用映射。

                                                                <b class="vimtag"> <a name="E565">E565</a> </b>
<code class="note">注意</code>: 补全激活时，不能递归使用插入模式，也不能改变缓冲区文本。以某种方式调用
":normal i.." 的映射将产生 E565 错误。

建议使用以下映射来使得输入补全命令简单一点 (不过它们可能屏蔽其它的命令): 
<code class="example">    :inoremap &lt;C-]&gt; &lt;C-X&gt;&lt;C-]&gt;</code>
<code class="example">    :inoremap &lt;C-F&gt; &lt;C-X&gt;&lt;C-F&gt;</code>
<code class="example">    :inoremap &lt;C-D&gt; &lt;C-X&gt;&lt;C-D&gt;</code>
<code class="example">    :inoremap &lt;C-L&gt; &lt;C-X&gt;&lt;C-L&gt;</code>
<code class="example"></code>
一个特例是，执行寄存器插入的 <code class="keystroke">CTRL-R</code> (见  <a href="insert.html#i_CTRL-R">i_CTRL-R</a> ) 不会退出 <code class="keystroke">CTRL-X</code> 模式。这主
要是为了允许通过使用 '=' 寄存器来调用若干函数来决定下一个操作。如果该寄存器的
内容 (或者 '=' 寄存器计算的结果) 不是合法的 <code class="keystroke">CTRL-X</code> 模式键，那么就会退出 <code class="keystroke">CTRL-X</code>
模式，如同键盘输入这些内容一样。

例如，下面的程序会如此映射 <code class="special">&lt;Tab&gt;</code>: 如果当前行只有空白，就插入 <code class="special">&lt;Tab&gt;</code>，不然就开始
或继续 <code class="keystroke">CTRL-N</code> 补全操作: 
<code class="example"></code>
<code class="example">        function! CleverTab()</code>
<code class="example">           if strpart( getline('.'), 0, col('.')-1 ) =~ '^\s*$'</code>
<code class="example">              return "\&lt;Tab&gt;"</code>
<code class="example">           else</code>
<code class="example">              return "\&lt;C-N&gt;"</code>
<code class="example">           endif</code>
<code class="example">        endfunction</code>
<code class="example">        inoremap &lt;Tab&gt; &lt;C-R&gt;=CleverTab()&lt;CR&gt;</code>
<code class="example"></code>
<code class="example"></code>
<code class="example"></code>
补全整行                                                <b class="vimtag"> <a name="compl-whole-line">compl-whole-line</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-L">i_CTRL-X_CTRL-L</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-L</code>           反向搜索和当前行光标前字符序列完全相同的行。忽略缩进。
                        找到的行插入在光标的前面。
                        <a href="options.html#'complete'">'complete'</a> 选项用来决定匹配在哪个缓冲区里搜索，已载入
                        和未载入的缓冲区都被使用。
        <code class="keystroke">CTRL-L</code>  或
        <code class="keystroke">CTRL-P</code>          反向搜索前一个匹配行。替换上一次匹配的行。

        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配行。替换上一次匹配的行。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-L</code>   在扩展一行以后，你可以通过接着输入 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-L</code> 得到
                        紧接着匹配行之后的行，直到见到两个 <code class="keystroke">CTRL-X</code> 为止。只能用
                        于已载入的缓冲区。

补全当前文件内的关键字                                  <b class="vimtag"> <a name="compl-current">compl-current</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-P">i_CTRL-X_CTRL-P</a> </b>
                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-N">i_CTRL-X_CTRL-N</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code>           正向搜索以光标前面的关键字开始的单词。找到的关键字插入
                        在光标的前面。

<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code>           反向搜索以光标前面的关键字开始的单词。找到的关键字插入
                        在光标的前面。

        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的关键字。替换上一次匹配的关键字。

        <code class="keystroke">CTRL-P</code>          反向搜索前一个匹配的关键字。替换上一次匹配的关键字。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 或
        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code>   继续使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 或 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code> 会复制上次本类
                        型补全在其它上下文里扩展的单词之后紧跟的单词，直到见到
                        两个 <code class="keystroke">CTRL-X</code> 为止。

如果在光标的前面有一个关键字 (由字母字符和 <a href="options.html#'iskeyword'">'iskeyword'</a> 指定的字符组成的名字)，
它的前面再加上 "\&lt;" (含义: 单词开始) 就被用作搜索模式。否则 "\&lt;\k\k" 被用作搜
索模式 (任何包含至少两个字符的关键字的开始)。

在替换模式下，替换的字符数目决定于匹配字符串的长度。这和直接在替换模式下键盘输
入经过替换的字符串类似。

如果光标前面不是一个合法的关键字字符，则匹配任何至少有两个字符的关键字。
        例如，要得到:
            printf("(%g, %g, %g)", vector[0], vector[1], vector[2]);
        只需输入:
            printf("(%g, %g, %g)", vector[0], ^P[1], ^P[2]);

搜索会在文件末尾回绕，这里不使用 <a href="options.html#'wrapscan'">'wrapscan'</a> 的值。

跳过多次重复的相同的补全内容；这样每次 <code class="keystroke">CTRL-N</code> 和 <code class="keystroke">CTRL-P</code> 都会插入不同的匹配 (除
非只有一个匹配的关键字)。

永远不会得到单个字符的匹配，因为它们通常不是你真想要的。
        例如，要得到:
                printf("name = %s\n", name);
        或者:
                printf("name = %s\n", n^P);
        甚至:
                printf("name = %s\n", ^P);
'\n' 中的 'n' 被跳过。

在扩展完一个词后，你可以使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code> 或 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 得到紧跟在扩展词
之后的单词。这些序列搜索刚刚扩展的文本，并且继续扩展之，使之包括另外一个词。这
可以用于你需要重复一系列复杂的单词的场合。尽管 <code class="keystroke">CTRL-P</code> 和 <code class="keystroke">CTRL-N</code> 只会找至少两个
字符的字符串，<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code> 和 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 可以用来扩展只有一个字符的单词。
        例如，要得到:
                M&amp;eacute;xico
        你可以输入:
                M^N^P^X^P^X^P
<code class="keystroke">CTRL-N</code> 开始一个扩展，而 <code class="keystroke">CTRL-P</code> 回到单个字符 "M"，然后后面的两个 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code>
分别得到 "&amp;eacute" 和 ";xico"。

如果上次的扩展因为超过 <a href="options.html#'textwidth'">'textwidth'</a> 被分割，则只会使用当前行的文本。

如果匹配在行尾，那么会插入下一行的首个单词，而且显示消息 "Word from other
line"。如果该词被接受，那么下个 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code> 或者 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 会搜索那些以
该单词开始的行。


补全 <a href="options.html#'dictionary'">'dictionary'</a> 的关键字                              <b class="vimtag"> <a name="compl-dictionary">compl-dictionary</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-K">i_CTRL-X_CTRL-K</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-K</code>           根据 <a href="options.html#'dictionary'">'dictionary'</a> 选项给出的文件搜索光标前关键字开始的
                        单词。这和 <code class="keystroke">CTRL-N</code> 类似，只不过搜索的是字典文件，而不是
                        当前文件。在光标之前插入找到的关键字。这可能很慢，因为
                        在用到第一个匹配之前，会先找到所有的匹配。缺省，
                        <a href="options.html#'dictionary'">'dictionary'</a> 选项为空。
                        关于哪里能找到单词列表的建议，见 <a href="options.html#'dictionary'">'dictionary'</a> 选项。
                        适用 <a href="options.html#'ignorecase'">'ignorecase'</a>、<a href="options.html#'smartcase'">'smartcase'</a> 和 <a href="options.html#'infercase'">'infercase'</a>。

        <code class="keystroke">CTRL-K</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的关键字。替换前次匹配的关键字。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的关键字。替换前次匹配的关键字。

补全 <a href="options.html#'thesaurus'">'thesaurus'</a> 的单词                                 <b class="vimtag"> <a name="compl-thesaurus">compl-thesaurus</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-T">i_CTRL-X_CTRL-T</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-T</code>           和 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-K</code> 类似，但稍有不同。它使用 <a href="options.html#'thesaurus'">'thesaurus'</a>
                        选项，而不是 <a href="options.html#'dictionary'">'dictionary'</a>。如果在同义词字典里找到匹
                        配，同一行里其余单词也会被列为匹配，即使它们并不补全单
                        词。这样一个单词可以被完全替换。

        <code class="keystroke">CTRL-T</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的关键字。替换前次匹配的关键字。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的关键字。替换前次匹配的关键字。

<a href="options.html#'thesaurus'">'thesaurus'</a> 选项使用的文件中，每行应该包含相近意思的单词，以非关键字字符分隔
(建议使用空白)。最大的行长为 510 个字节。

举一个例子，假想 <a href="options.html#'thesaurus'">'thesaurus'</a> 文件有一行形如: 
<code class="example">        angry furious mad enraged</code>
把光标放在字母 "ang" 之后并输入 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-T</code> 会匹配单词 "angry"；继续按会把单
词改为 "furious"、"mad" 等等。

其它的用法包括在两种语言之间的翻译，或者用关键字给 API 函数归类等等。


此 github 议题附加了英语单词列表:
<a href="https://github.com/vim/vim/issues/629#issuecomment-443293282">https://github.com/vim/vim/issues/629#issuecomment-443293282</a>
解包 thesaurus_pkg.zip，把 thesaurus.txt 文件放在某处，如
~/.vim/thesaurus/english.txt，然后把 <a href="options.html#'thesaurus'">'thesaurus'</a> 选项设为此文件名。


用 <a href="options.html#'thesaurusfunc'">'thesaurusfunc'</a> 补全关键字                           <b class="vimtag"> <a name="compl-thesaurusfunc">compl-thesaurusfunc</a> </b>

如果设置了 <a href="options.html#'thesaurusfunc'">'thesaurusfunc'</a> 选项，执行用户指定函数来生成补全匹配的列表，忽略
<a href="options.html#'thesaurus'">'thesaurus'</a> 选项。 <a href="insert.html#complete-functions">complete-functions</a>  有关于如何调用函数和返回何种值的说明。

以下是使用 "aiksaurus" 命令的例子 (Magnus Groß 提供): 
<code class="example"></code>
<code class="example">    func Thesaur(findstart, base)</code>
<code class="example">      if a:findstart</code>
<code class="example">        return searchpos('\&lt;', 'bnW', line('.'))[1] - 1</code>
<code class="example">      endif</code>
<code class="example">      let res = []</code>
<code class="example">      let h = ''</code>
<code class="example">      for l in systemlist('aiksaurus ' .. shellescape(a:base))</code>
<code class="example">        if l[:3] == '=== '</code>
<code class="example">          let h = '(' .. substitute(l[4:], ' =*$', ')', '')</code>
<code class="example">        elseif l ==# 'Alphabetically similar known words are: '</code>
<code class="example">          let h = "\U0001f52e"</code>
<code class="example">        elseif l[0] =~ '\a' || (h ==# "\U0001f52e" &amp;&amp; l[0] ==# "\t")</code>
<code class="example">          call extend(res, map(split(substitute(l, '^\t', '', ''), ', '), {_, val -&gt; {'word': val, 'menu': h}}))</code>
<code class="example">        endif</code>
<code class="example">      endfor</code>
<code class="example">      return res</code>
<code class="example">    endfunc</code>
<code class="example"></code>
<code class="example">    if exists('+thesaurusfunc')</code>
<code class="example">      set thesaurusfunc=Thesaur</code>
<code class="example">    endif</code>
<code class="example"></code>
<code class="example"></code>
补全当前文件及其头文件内的关键字                        <b class="vimtag"> <a name="compl-keyword">compl-keyword</a> </b>

<a href="options.html#'include'">'include'</a> 选项指定如何找到含有头文件名字的行。<a href="options.html#'path'">'path'</a> 选项用来搜索头文件。

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-I">i_CTRL-X_CTRL-I</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-I</code>           搜索当前文件及其头文件里第一个以光标前面的字母序列开始
                        的关键字。在光标的前面插入找到的关键字。

        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的关键字。替换前次匹配的关键字。
                        <code class="note">注意</code>: <code class="keystroke">CTRL-I</code> 和 <code class="special">&lt;Tab&gt;</code> 相同，而这可能会在成功的补全之后
                        输入，因此不使用 <code class="keystroke">CTRL-I</code> 来搜索下一个匹配。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的关键字。替换前次匹配的关键字。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-I</code>   继续使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-I</code> 会复制上次本类型补全在其它上下
                        文里扩展的单词之后紧跟的单词，直到见到两个 <code class="keystroke">CTRL-X</code> 为
                        止。

补全标签                                                <b class="vimtag"> <a name="compl-tag">compl-tag</a> </b>
                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-]">i_CTRL-X_CTRL-]</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-]</code>           搜索第一个以光标前面的字母序列开始的标签。在光标前面插
                        入匹配的标签。标签名可以包含字母字符和由 <a href="options.html#'iskeyword'">'iskeyword'</a>
                        决定的字符 (这和关键字相同)。另见  <a href="tagsrch.html#CTRL-]">CTRL-]</a> 。
                        <a href="options.html#'showfulltag'">'showfulltag'</a> 选项可以用来增加标签定义前后的上下文。
        <code class="keystroke">CTRL-]</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的标签。替换前次匹配的标签。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的标签。替换前次匹配的标签。


补全文件名                                              <b class="vimtag"> <a name="compl-filename">compl-filename</a> </b>
                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-F">i_CTRL-X_CTRL-F</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-F</code>           搜索第一个以光标前面的字母序列开始的文件。在光标前面插
                        入匹配的文件。文件名可以包含字母字符和由 <a href="options.html#'isfname'">'isfname'</a> 决
                        定的字符。<code class="note">注意</code>，(目前) 这里不使用 <a href="options.html#'path'">'path'</a> 选项。
        <code class="keystroke">CTRL-F</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的文件名。替换前次匹配的文件名。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的文件名。替换前次匹配的文件名。


补全定义或宏                                            <b class="vimtag"> <a name="compl-define">compl-define</a> </b>

<a href="options.html#'define'">'define'</a> 选项用来指定包含定义的行。<a href="options.html#'include'">'include'</a> 选项用来指定包含头文件名的行。
<a href="options.html#'path'">'path'</a> 选项用来搜索头文件。

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-D">i_CTRL-X_CTRL-D</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-D</code>           搜索当前和头文件里第一个以光标前面的字母序列开始的
                        定义 (或宏)。在光标的前面插入找到的定义名。
        <code class="keystroke">CTRL-D</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的定义。替换前次匹配的定义。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的定义。替换前次匹配的定义。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-D</code>   继续使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-D</code> 会复制上次本类型补全在其它上下
                        文里扩展的单词之后紧跟的单词，直到见到两个 <code class="keystroke">CTRL-X</code> 为
                        止。


补全 Vim 命令                                           <b class="vimtag"> <a name="compl-vim">compl-vim</a> </b>

这里，补全是上下文敏感的，和命令行上的情况相似。它既能补全 Ex 命令，又能补全它
的参数。可用于编写 Vim 脚本。

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-V">i_CTRL-X_CTRL-V</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-V</code>           猜测光标前的项目的条目，并找到第一个匹配。
                        <code class="note">注意</code>: 如果 <code class="keystroke">CTRL-V</code> 被映射，你通常可以用 <code class="keystroke">CTRL-Q</code> 来代替
                         <a href="insert.html#i_CTRL-Q">i_CTRL-Q</a> 。
        <code class="keystroke">CTRL-V</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配。替换前次匹配。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配。替换前次匹配。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-V</code>   继续使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-V</code> 和 <code class="keystroke">CTRL-V</code> 一样。这允许键映射执
                        行 Vim 命令补全，例如: 
<code class="example">                                :imap &lt;Tab&gt; &lt;C-X&gt;&lt;C-V&gt;</code>
<code class="example"></code>
用户定义补全                                            <b class="vimtag"> <a name="compl-function">compl-function</a> </b>

命令补全可以由用户通过 <a href="options.html#'completefunc'">'completefunc'</a> 选项自定义一个函数来完成。下面说明如何调
用此函数，并提供示例  <a href="insert.html#complete-functions">complete-functions</a> 。

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-U">i_CTRL-X_CTRL-U</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-U</code>           猜测光标前面项目的类型，并寻找它的第一个匹配。
        <code class="keystroke">CTRL-U</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配。替换前次匹配。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配。替换前次匹配。


全能 (omni) 补全                                        <b class="vimtag"> <a name="compl-omni">compl-omni</a> </b>

命令补全可以由用户通过 <a href="options.html#'omnifunc'">'omnifunc'</a> 选项自定义一个函数来完成。这通常用于特定文件
类型的补全。

下面说明如何调用此函数，并提供示例  <a href="insert.html#complete-functions">complete-functions</a> 。
关于特定文件类型的说明，见  <a href="insert.html#compl-omni-filetypes">compl-omni-filetypes</a> 。
将来会有更多补全脚本，欢迎查阅 www.vim.org。目前已经有了 C++ 的首个版本。

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-O">i_CTRL-X_CTRL-O</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code>           猜测光标前面项目的类型，并寻找它的第一个匹配。
        <code class="keystroke">CTRL-O</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配。替换前次匹配。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配。替换前次匹配。


拼写建议                                                <b class="vimtag"> <a name="compl-spelling">compl-spelling</a> </b>

定位光标所在或之前的单词，然后提出正确拼写的单词作为建议进行替代。如果该行里有
一个错误拼写的单词在光标之前或之下，移动光标到它后面。否则，使用刚刚在光标之前
的那个单词来提出建议，即使该单词没有拼写错误。

<code class="note">NOTE:</code> 很多 Unix 终端上，<code class="keystroke">CTRL-S</code> 暂停显示。这时用 's' 可以代替。如果显示暂停，输
入 <code class="keystroke">CTRL-Q</code> 会继续显示。

                                                <b class="vimtag"> <a name="i_CTRL-X_CTRL-S">i_CTRL-X_CTRL-S</a> </b> <b class="vimtag"> <a name="i_CTRL-X_s">i_CTRL-X_s</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-S</code>  或
<code class="keystroke">CTRL-X</code> s                定位光标之前的单词，并寻找它的第一个拼写建议。
        <code class="keystroke">CTRL-S</code>  或
        <code class="keystroke">CTRL-N</code>          正向搜索下一个建议。替换前次的建议。 <code class="note">注意</code> 这里不能用
                        's'。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个建议。替换前次的建议。


从不同的来源补全关键字                                  <b class="vimtag"> <a name="compl-generic">compl-generic</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-N">i_CTRL-N</a> </b>
<code class="keystroke">CTRL-N</code>                  在 <a href="options.html#'complete'">'complete'</a> 选项给出的地方搜索下一个以光标前面的关键
                        字开始的单词。在光标的前面插入找到的关键字名。

                                                        <b class="vimtag"> <a name="i_CTRL-P">i_CTRL-P</a> </b>
<code class="keystroke">CTRL-P</code>                  在 <a href="options.html#'complete'">'complete'</a> 选项给出的地方搜索上一个以光标前面的关键
                        字开始的单词。在光标的前面插入找到的关键字名。

        <code class="keystroke">CTRL-N</code>          正向搜索下一个匹配的关键字。替换前次匹配的关键字。

        <code class="keystroke">CTRL-P</code>          反向搜索下一个匹配的关键字。替换前次匹配的关键字。

        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 或
        <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code>   继续使用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-N</code> 或 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-P</code> 会复制上次本类
                        型补全在其它上下文里扩展的单词之后紧跟的单词，直到见到
                        两个 <code class="keystroke">CTRL-X</code> 为止。


停止补全                                                <b class="vimtag"> <a name="compl-stop">compl-stop</a> </b>

                                                        <b class="vimtag"> <a name="i_CTRL-X_CTRL-Z">i_CTRL-X_CTRL-Z</a> </b>
<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-Z</code>           停止补全而不改变原有的文本。


寻 找 补 全 的 函 数                                    <b class="vimtag"> <a name="complete-functions">complete-functions</a> </b>

这里指 <a href="options.html#'completefunc'">'completefunc'</a>、<a href="options.html#'thesaurusfunc'">'thesaurusfunc'</a> 和 <a href="options.html#'omnifunc'">'omnifunc'</a>。

函数被调用两次，使用不同的方式:
- 首先，调用函数以寻找补全文本的开始位置。
- 然后，调用函数以寻找实际的匹配。

第一次调用时，参数是:
   a:findstart  1
   a:base       空

函数必须返回补全开始位置的列数，这个数字必须在零到光标所在列 "col('.')" 之间。
过程应该检查光标之前的字符，并包含那些可能成为补全项一部分的字符。该列到光标列
之间的文本将来会被匹配结果替换。如果返回值大于光标列，则使用光标列。

负返回值:
   -2   安静的撤销，留在补全模式。
   -3   安静的撤销，退出补全模式。
   其它负值: 补全从光标列开始

第二次调用时，参数是:
   a:findstart  0
   a:base       补全必须匹配的文本；即第一次调用定位的文本 (可以为空)

函数必须返回匹配单词的列表。这些匹配通常包含 "a:base" 文本。如果没有匹配，返回
空列表。<code class="note">注意</code> 第一次调用后，光标可能移动过，文本也可能有所改动。

要知道关于匹配词的信息，返回包含匹配列表的一个字典。字典包含以下项目:
        words           包含匹配单词的列表 (必需)。
        refresh         用于控制函数重新启动的字符串 (可选)。
                        目前唯一支持的值是 "always"。效果是每次前导文本改变时
                        都会调用函数。

如果不想看空返回值引起的<code class="note">警告</code>信息，可返回  <a href="eval.html#v:none">v:none</a> 。可用于通过  <a href="builtin.html#complete()">complete()</a>  来
实现异步补全。

忽略其他项目。

要在补全结束之后有动作，参见  <a href="autocmd.html#CompleteDonePre">CompleteDonePre</a>  和  <a href="autocmd.html#CompleteDone">CompleteDone</a>  自动命令事
件。

例如，函数里可以这么做: 
<code class="example">        let matches = ... 单词列表 ...</code>
<code class="example">        return {'words': matches, 'refresh': 'always'}</code>

                                                <b class="vimtag"> <a name="complete-items">complete-items</a> </b>
每个列表项可以是字符串或者字典类型。如果是字符串，直接用作补全文本。如果是字
典，可以包含以下各项:
        word            需要插入的文本，必需
        abbr            "word" 的缩写；如果非空，菜单里使用它而不是 "word"
        menu            用于弹出菜单的补充文本，在 "word" 或 "abbr" 之后显示
        info            关于补全项的更多信息，能够在预览或弹出窗口显示
        kind            代表补全类型的单个字母
        icase           如果非零，比较项目是否等同时忽略大小写；如果省略就假定
                        为零，这时可以同时加入只有大小写有差异的匹配项
        equal           如果非零，总是在比较时把此项当成相等。这意味着，
                        "equal=1" 关闭此项的过滤。
        dup             如果非零，那么即使和此匹配包含相同单词的匹配项已经存在
                        也无妨。
        empty           如果非零，匹配项即使是空字符串也会加入
        user_data       和项目相关联的定制数据，可从  <a href="eval.html#v:completed_item">v:completed_item</a>  得到；
                        可以是任何类型；缺省为空串

除了 "icase"、"equal"、"dup" 和 "empty" 以外，其它各项必须是字符串。如果有一项
不合要求，报错，而列表的其余项目也不再使用。你可以在返回列表中混用字符串和字典
项目。

"menu" 项目用于弹出菜单且可能被截短，所以它应该尽量简短。"info" 项目可以稍长。
如果在 <a href="options.html#'completeopt'">'completeopt'</a> 中包含 "preview"，使用预览窗口来显示该项信息，如果在
<a href="options.html#'completeopt'">'completeopt'</a> 中包含 "popup"，则使用弹出窗口。在预览窗口中关闭弹出菜单后，
"info" 项目将保留显示，这对录入函数参数很有用。用单个空格设置 "info" 可以清除
预览窗口现存的文本。预览窗口的大小缺省是三行，但在 <a href="options.html#'previewheight'">'previewheight'</a> 为 1 或 2
时使用其值。

                                                <b class="vimtag"> <a name="complete-popup">complete-popup</a> </b>
如果 <a href="options.html#'completeopt'">'completeopt'</a> 中有 "popup"，使用弹出窗口显示 "info"。这时 <a href="options.html#'completepopup'">'completepopup'</a>
选项指定弹出的属性，在 info 弹出建立时使用。此选项是逗号分隔的值列表:
        height          弹出的最大高度
        width           弹出的最大宽度
        highlight       弹出的高亮组 (缺省是 PmenuSel)
        align           "item" (缺省) 或 "menu"
        border          "on" (缺省) 或 "off"
例如: 
<code class="example">        :set completepopup=height:10,width:60,highlight:InfoPopup</code>
<code class="example"></code>
如果 "align" 值是 "item"，弹出的位置靠近选择的项目。改变选择也会移动弹出。如果
"align" 是 "menu"，如果菜单在文本之下，弹出和菜单顶部对齐，否则和菜单底部对
齐。

info 弹出被创建后，可在  <a href="popup.html#popup_findinfo()">popup_findinfo()</a>  里找到，其属性可由
 <a href="popup.html#popup_setoptions()">popup_setoptions()</a>  改变。

                                                <b class="vimtag"> <a name="complete-popuphidden">complete-popuphidden</a> </b>
如果是通过异步获取弹出的信息，在 <a href="options.html#'completeopt'">'completeopt'</a> 中用 "popuphidden"。info 弹出会
先被隐藏，一旦 info 被填充，必须调用  <a href="popup.html#popup_show()">popup_show()</a> 。可通过  <a href="autocmd.html#CompleteChanged">CompleteChanged</a> 
自动命令完成，就像这样: 
<code class="example">        set completeopt+=popuphidden</code>
<code class="example">        au CompleteChanged * call UpdateCompleteInfo()</code>
<code class="example">        func UpdateCompleteInfo()</code>
<code class="example">          " 取消任何进行中的 info 获取</code>
<code class="example">          let item = v:event.completed_item</code>
<code class="example">          " 开始获取项目的 info，然后调用 ShowCompleteInfo(info)</code>
<code class="example">        endfunc</code>
<code class="example">        func ShowCompleteInfo(info)</code>
<code class="example">          let id = popup_findinfo()</code>
<code class="example">          if id</code>
<code class="example">            call popup_settext(id, 'async info: ' .. a:info)</code>
<code class="example">            call popup_show(id)</code>
<code class="example">          endif</code>
<code class="example">        endfunc</code>
<code class="example"></code>
                                                <b class="vimtag"> <a name="complete-item-kind">complete-item-kind</a> </b>
"kind" 项目用单一字母表示补全类型。用它可以指定补全的不同显示方式 (不同颜色或
者图标)。目前，可用如下类型:
        v       变量
        f       函数或方法
        m       结构或类成员
        t       typedef
        d       #define 或宏

如果搜索匹配耗时较长，可以调用  <a href="builtin.html#complete_add()">complete_add()</a>  向总列表中增加每个匹配。不要在
返回的列表里包含这些匹配！搜索匹配的同时，时不时地调用  <a href="builtin.html#complete_check()">complete_check()</a>  来使
得用户仍然可以按键。如果该函数返回非零，搜索停止。

                                                        <b class="vimtag"> <a name="E840">E840</a> </b>
该函数可以移动光标，结束后光标会恢复。
该函数不允许移动到其他窗口，也不允许删除文本。

一个补全月份名的示例: 
<code class="example">        fun! CompleteMonths(findstart, base)</code>
<code class="example">          if a:findstart</code>
<code class="example">            " 定位单词的开始处</code>
<code class="example">            let line = getline('.')</code>
<code class="example">            let start = col('.') - 1</code>
<code class="example">            while start &gt; 0 &amp;&amp; line[start - 1] =~ '\a'</code>
<code class="example">              let start -= 1</code>
<code class="example">            endwhile</code>
<code class="example">            return start</code>
<code class="example">          else</code>
<code class="example">            " 寻找匹配 "a:base" 的月份</code>
<code class="example">            let res = []</code>
<code class="example">            for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")</code>
<code class="example">              if m =~ '^' .. a:base</code>
<code class="example">                call add(res, m)</code>
<code class="example">              endif</code>
<code class="example">            endfor</code>
<code class="example">            return res</code>
<code class="example">          endif</code>
<code class="example">        endfun</code>
<code class="example">        set completefunc=CompleteMonths</code>

功能同上，但是现在假设搜索比较慢: 
<code class="example">        fun! CompleteMonths(findstart, base)</code>
<code class="example">          if a:findstart</code>
<code class="example">            " 定位单词的开始处</code>
<code class="example">            let line = getline('.')</code>
<code class="example">            let start = col('.') - 1</code>
<code class="example">            while start &gt; 0 &amp;&amp; line[start - 1] =~ '\a'</code>
<code class="example">              let start -= 1</code>
<code class="example">            endwhile</code>
<code class="example">            return start</code>
<code class="example">          else</code>
<code class="example">            " 寻找匹配 "a:base" 的月份</code>
<code class="example">            for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")</code>
<code class="example">              if m =~ '^' .. a:base</code>
<code class="example">                call complete_add(m)</code>
<code class="example">              endif</code>
<code class="example">              sleep 300m        " simulate searching for next match</code>
<code class="example">              if complete_check()</code>
<code class="example">                break</code>
<code class="example">              endif</code>
<code class="example">            endfor</code>
<code class="example">            return []</code>
<code class="example">          endif</code>
<code class="example">        endfun</code>
<code class="example">        set completefunc=CompleteMonths</code>


插 入 补 全 弹 出 菜 单                                 <b class="vimtag"> <a name="ins-completion-menu">ins-completion-menu</a> </b>
                                                        <b class="vimtag"> <a name="popupmenu-completion">popupmenu-completion</a> </b>
Vim 可以用更简单的弹出菜单来显示匹配。

当下面条件符合时使用弹出菜单:
- <a href="options.html#'completeopt'">'completeopt'</a> 选项包含 "menu" 或 "menuone"。
- 显示终端至少支持 8 色。
- 至少有两条匹配项。如果使用 "menuone"，一条匹配也可以。

选项 <a href="options.html#'pumheight'">'pumheight'</a> 用于设置最大高度。默认值是使用全部有效空间。
选项 <a href="options.html#'pumwidth'">'pumwidth'</a> 用于设置最小宽度。默认值是 15 个字符。

有三个状态:
1. 插入了完整的匹配，例如在 <code class="keystroke">CTRL-N</code> 或 <code class="keystroke">CTRL-P</code> 之后。
2. 用光标键选择其它匹配项。此时不插入该匹配项，只在弹出菜单中高亮选中的条目。
3. 只插入了部分匹配文本，并且已经输入字符或者使用了退格键，这时匹配项列表根据
   光标前的内容进行调整。

开始时你通常处于状态一并插入第一个匹配。如果 <a href="options.html#'completeopt'">'completeopt'</a> 包含了 "longest" 而
且有多个匹配项，那么开始于状态三。

如果选择其它匹配项，例如键入 <code class="keystroke">CTRL-N</code> 或 <code class="keystroke">CTRL-P</code>，就进入了状态一。这不会改变匹配
项列表。

如果退回到原文，就会处于状态三。要立即进入该状态，可以使用快捷键映射方法，该映
射在补全开始后立即使用 <code class="keystroke">CTRL-P</code>: 
<code class="example">        :imap &lt;F7&gt; &lt;C-N&gt;&lt;C-P&gt;</code>

                                                <b class="vimtag"> <a name="popupmenu-keys">popupmenu-keys</a> </b>
在状态一下，这些键有特别的含义:
<code class="special">&lt;BS&gt;</code> 和 <code class="keystroke">CTRL-H</code>    删除一个字符，查找光标前单词的匹配项。这会减少列表中匹配项的
                  数目，常常到只有一个项目，然后切换到状态二。
其它非特殊字符:
                  停止补全，不改变匹配，然后插入输入的字符。

在状态二和状态三下，这些键有特别的含义:
<code class="special">&lt;BS&gt;</code> 和 <code class="keystroke">CTRL-H</code>    删除一个字符，并查找光标前变短的单词的匹配项。这可能会发现更
                  多的匹配项。
<code class="keystroke">CTRL-L</code>            从当前匹配项中增加一个字符，可能会减少匹配项的数量。
任何可显示的非空白字符:
                  加入该字符，减少匹配项的数量。

在全部三个状态下，可以使用以下这些键:
<code class="keystroke">CTRL-Y</code>            是 (Yes): 接受当前选择的匹配项并停止补全。
<code class="keystroke">CTRL-E</code>            结束 (End) 补全，回退到选择匹配前原有的内容 (原先输入的或者
                  最长的公共字符串)。
<code class="special">&lt;PageUp&gt;</code>          反向若干项选择一个匹配项，但不插入。
<code class="special">&lt;PageDown&gt;</code>        正向若干项选择一个匹配项，但不插入。
<code class="special">&lt;Up&gt;</code>              选择前一个匹配，同 <code class="keystroke">CTRL-P</code>，但不插入。
<code class="special">&lt;Down&gt;</code>            选择后一个匹配，同 <code class="keystroke">CTRL-N</code>，但不插入。
<code class="special">&lt;Space&gt;</code> 或 <code class="special">&lt;Tab&gt;</code>  停止补全，不改变匹配，插入键入的字符

<code class="special">&lt;Enter&gt;</code> 键的行为取决于你现在所处的状态:
状态一:           使用现有的文本，然后插入换行符。
状态二:           插入当前选择项。
状态三:           使用现有的文本，然后插入换行符。

换句话说: 如果你只使用光标键在匹配项列表中选择其它条目，按 <code class="special">&lt;Enter&gt;</code> 键将插入该
匹配。如果键入其它字符，按 <code class="special">&lt;Enter&gt;</code> 键将插入换行符。


下面的高亮组能够改变菜单颜色:
Pmenu           普通项  <a href="syntax.html#hl-Pmenu">hl-Pmenu</a> 
PmenuSel        选中项  <a href="syntax.html#hl-PmenuSel">hl-PmenuSel</a> 
PmenuSbar       滚动条  <a href="syntax.html#hl-PmenuSbar">hl-PmenuSbar</a> 
PmenuThumb      滚动条拇指 (thumb)  <a href="syntax.html#hl-PmenuThumb">hl-PmenuThumb</a> 

显示弹出窗口时，没有专门的映射。但你可以使用插入模式映射并检查  <a href="builtin.html#pumvisible()">pumvisible()</a> 
函数的返回值以进行不同的处理。例如: 
<code class="example">        :inoremap &lt;Down&gt; &lt;C-R&gt;=pumvisible() ? "\&lt;lt&gt;C-N&gt;" : "\&lt;lt&gt;Down&gt;"&lt;CR&gt;</code>
<code class="example"></code>
映射中用 <code class="special">&lt;expr&gt;</code> 可以在键入某字符或者满足某些条件时弹出菜单。例如，键入 '.': 
<code class="example">        inoremap &lt;expr&gt; . MayComplete()</code>
<code class="example">        func MayComplete()</code>
<code class="example">            if (can complete)</code>
<code class="example">              return ".\&lt;C-X&gt;\&lt;C-O&gt;"</code>
<code class="example">            endif</code>
<code class="example">            return '.'</code>
<code class="example">        endfunc</code>
<code class="example"></code>
详见  <a href="map.html#:map-%3Cexpr%3E">:map-&lt;expr&gt;</a> 。


特 定 文 件 类 型 全 能 补 全 的 补 充 说 明        <b class="vimtag"> <a name="compl-omni-filetypes">compl-omni-filetypes</a> </b>

文件类型 <code class="special">{filetype}</code> 使用的是 <a href="options.html#'runtimepath'">'runtimepath'</a> 的 autoload/<code class="special">{filetype}</code>complete.vim
文件。比如对于 "java"，就是文件 autoload/javacomplete.vim。


C                                                       <b class="vimtag"> <a name="ft-c-omni">ft-c-omni</a> </b>

C 代码补全需要标签文件。你应该使用 Universal/Exuberant ctags 软件，因为它会加
入补全所需要的额外信息。你可以在这里找到它:
        Universal Ctags: <a href="https://ctags.io">https://ctags.io</a>
        Exuberant Ctags: <a href="http://ctags.sourceforge.net">http://ctags.sourceforge.net</a>

推荐使用 Universal Ctags，Exuberant Ctags 已不再开发。

对 Exuberant ctags 而言，建议使用 5.6 或更新版本。对于 5.5.4 版本，你应该打上
增加 "typename:" 字段的补丁:
        ftp://ftp.vim.org/pub/vim/unstable/patches/ctags-5.5.4.patch
可以在这里找到 MS-Windows 上已经编译好的可执行版本:
        <a href="http://ctags.sourceforge.net/">http://ctags.sourceforge.net/</a>
        <a href="https://github.com/universal-ctags/ctags-win32">https://github.com/universal-ctags/ctags-win32</a>

如果你想补全系统函数，可以用 ctags 生成包含所有系统头文件的标签文件: 
<code class="example">        % ctags -R -f ~/.vim/systags /usr/include /usr/local/include</code>
在 vimrc 文件中，把这个标签文件增加到 <a href="options.html#'tags'">'tags'</a> 选项中: 
<code class="example">        set tags+=~/.vim/systags</code>
<code class="example"></code>
如果在不包含 "." 或 "=" 的名字后面用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code>，会直接从标签文件中补全。这
适用于任何标识符，包括函数名。如果你想补全标签文件没有的局部变量名，用 <code class="keystroke">CTRL-P</code>
代替。

如果在包含 "." 或 "=" 的名字后面用 <code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code>，Vim 会试图识别变量类型并指出
它所含的成员。这意味着只会列出该变量的有效成员。

如果成员名字已经完整，<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code> 会为复合类型加上 "." 或 "-&gt;"。

Vim 没有包含 C 编译器，它只能识别使用明确格式的声明。预处理器指令可能会引起混
淆。如果在多个位置里定义了同样的结构名，所有可能的结构成员都会被包括。


CSS                                                     <b class="vimtag"> <a name="ft-css-omni">ft-css-omni</a> </b>

遵循 CSS 2.1 标准来补全属性和相应的值。


HTML                                                    <b class="vimtag"> <a name="ft-html-omni">ft-html-omni</a> </b>
XHTML                                                   <b class="vimtag"> <a name="ft-xhtml-omni">ft-xhtml-omni</a> </b>

<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code> 能够补全 (X)HTML 文件的各种元素。它是为了支持编写 XHTML 1.0
Strict 文件而设计的，但也可用于其它 HTML 版本。特性:

- "&lt;" 之后，根据上下文补全标签名 (在标签内部，不给出 div 标签建议)；'/&gt;' 表明
  空标签
- 在标签中，补全合适的属性 (不包括标签的 width 属性)；同时显示属性类型；'*' 表
  明必需的属性
- 如果属性只有有限的几个可能值，用它们来补全
- 补全实体 (entity) 名
- 根据 <code class="special">&lt;style&gt;</code> 标签和包含的 CSS 文件里提取的数据，补全 "class" 和 "id" 属性值
- 对 "style" 属性值或在 "style" 标签内部补全时，切换到  <a href="insert.html#ft-css-omni">ft-css-omni</a>  补全
- 对事件属性值或在 "script" 标签内部补全时，切换到  <a href="insert.html#ft-javascript-omni">ft-javascript-omni</a>  补全
- "&lt;/" 之后，<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code> 会关闭最近打开的标签

<code class="note">备注</code>: 如果是第一次使用，补全菜单的显示会有少许延迟--这点时间用于数据文件载入。
<code class="note">备注</code>: 补全可能会在错误格式的文档中失效。在这种情况下，请尝试运行  <a href="quickfix.html#:make">:make</a>  命令
检查格式问题。


HTML 类型                                               <b class="vimtag"> <a name="html-flavor">html-flavor</a> </b>

默认的 HTML 补全机制依赖于文件类型: HTML 文件使用 HTML 4.01 Transitional 标准
(<a href="options.html#'filetype'">'filetype'</a> 是 <code class="badlink">'html'</code>)，XHTML 使用 XHTML 1.0 Strict 标准 (<a href="options.html#'filetype'">'filetype'</a> 是
<code class="badlink">'xhtml'</code>)。

如果在任何标签的外部进行补全，你可以选择 DOCTYPE，然后载入合适的数据文件，并用
于后面所有的补全操作。

关于数据文件格式更多的信息见  <a href="insert.html#xml-omni-datafile">xml-omni-datafile</a> 。vim 的线上站点 ( <a href="intro.html#www">www</a> ) 可以
找到一些数据文件。

<code class="note">注意</code> b:html_omni_flavor 可以指向任何使用 XML 数据的文件。这就使混合 PHP
( <a href="insert.html#ft-php-omni">ft-php-omni</a> ) 和任何 XML 方言的补全成为可能 (假设你有相应的数据文件)。如果该
变量没有设置，使用 XHTML 1.0 Strict 标准。


JAVASCRIPT                                             <b class="vimtag"> <a name="ft-javascript-omni">ft-javascript-omni</a> </b>

补全绝大部分 JavaScript 语言和 DOM 元素。

补全:

- 变量
- 函数名；显示函数参数
- 函数参数
- 变量属性，试图检测变量类型
- 根据上下文补全 DOM 对象和属性
- 语言中的关键字

补全机制可以用于单独的 JavaScript 文件 (&amp;ft==javascript)、(X)HTML 的 <code class="special">&lt;script&gt;</code>
标签内部和事件的属性值 (包含对外部文件的扫描)。

DOM 兼容性

当前 (2006 年初) 有两种主要浏览器 - MS Internet Explorer 和 Mozilla Firefox。
这两个软件市场占有率达到 90% 以上。理论上，W3C 组织 (<a href="http://www.w3c.org">http://www.w3c.org</a>) 建立
标准，但是这些标准并没有完全遵守和实现。

<code class="section">                IE      FF      W3C  全能补全 </code>
<code class="section">                +/-     +/-     +    +               </code>
<code class="section">                +       +       -    +               </code>
<code class="section">                +       -       -    -               </code>
<code class="section">                -       +       -    -               </code>

不管浏览器的实现进度如何，补全插件总是把标准定义的元素放入建议列表。两个主要浏
览器都实现但标准没有覆盖的元素也作为建议。而其它的元素则不出现于建议列表。


PHP                                                     <b class="vimtag"> <a name="ft-php-omni">ft-php-omni</a> </b>

PHP 代码的补全需要标签文件才能对外部文件的数据和类进行补全。应该使用
Universal/Exuberant ctags 5.5.4 版本或更新的版本。在这里可以找到它:

        Universal Ctags: <a href="https://ctags.io">https://ctags.io</a>
        Exuberant Ctags: <a href="http://ctags.sourceforge.net">http://ctags.sourceforge.net</a>

脚本对以下项目进行补全:

- $ 变量名之后
  - 如果变量声明为对象，加上 "-&gt;"，如果标签文件有效，显示类名
  - 在 "-&gt;" 之后，只补全给定类中的函数和变量名。为了查找类的位置和内容，需要标
    签文件。因为 PHP 不是强类型的语言，用户可以使用 @var 标签来声明类: 
<code class="example"></code>
<code class="example">        /* @var $myVar myClass */</code>
<code class="example">        $myVar-&gt;</code>

    不过，要找到 myClass 的内容，仍然需要标签文件。

- 带有附加信息的函数名:
  - 如果是内建函数，列出可能的参数，在 | 之后列出函数返回的数据类型
  - 如果是用户函数，列出参数和函数定义所在的文件名 (如果不是当前文件)

- 常量名
- 在 "new" 声明之后的类名


<code class="note">注意</code>: 如果第一次调用补全功能，Vim 会把所有需要的数据载入内存。这可能需要几秒
钟。下次补全时，就几乎感觉不到延迟了。

脚本检测光标是否在 &lt;?php ?&gt; 标签内。如果不是，会自动切换到 HTML/CSS/JavaScript
补全。<code class="note">注意</code>: 和原始 HTML 文件不同，标签补全 (也仅对标签补全而言) 和上下文无关。


RUBY                                                    <b class="vimtag"> <a name="ft-ruby-omni">ft-ruby-omni</a> </b>

Ruby 代码的补全需要 Vim 编译时带  <a href="various.html#+ruby">+ruby</a>  特性。

Ruby 补全会因需分析你的缓冲区以提供补全列表。它会从 <code class="badlink">'require'</code> 载入的和当前缓冲
区定义的模块里提取补全。

<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code> 提供的补全是上下文相关的:

<code class="section">          上 下 文                        提 供 的 补 全 </code>

 1. 不在类定义中                     类名、常量和全局变量

 2. 类定义中                         这个类所定义的方法或常量

 3. '.'、'::' 或者 ':' 之后          被解除参照的对象所适用的方法

 4. ':' 或者 ':foo' 之后             符号名 (<code class="badlink">'foo'</code> 起始的那些)

<code class="note">备注</code>:
 - Vim 会载入/执行程序代码，以便提供补全。这可能会导致部分代码被执行。这一点也
   许值得关注。缺省行为不再打开这一功能。如果需要此特性，加上 
<code class="example">     let g:rubycomplete_buffer_loading = 1</code>
- 在第 1 点中，Vim 可以解析整个缓冲区以获得用作补全结果的类名列表。默认关闭此
   功能。要使其生效，在 vimrc 里加入 
<code class="example">     let g:rubycomplete_classes_in_global = 1</code>
- 在第 2 点中，不支持匿名类。
 - 在第 3 点中，Vim 会试图判断对象所支持的方法。
 - Vim 可以检测和载入 Rails 环境并用于 rails 项目的文件。默认关闭此特性。要使
   其生效，在 vimrc 里加入 
<code class="example">     let g:rubycomplete_rails = 1</code>


SYNTAX                                                  <b class="vimtag"> <a name="ft-syntax-omni">ft-syntax-omni</a> </b>

Vim 能够对将近 500 种语言进行语法高亮。高亮支持的一部分是需要知道构成语言的关
键字。许多文件类型已经有专门的补全脚本，而对其它的文件类型而言，syntaxcomplete
脚本可以提供基本的补全。实现的方法是用 Vim 知道如何色彩高亮的那些文本来构造全
能补全列表。它适用于任何文件类型，并可以提供基本但和语言相关的补全机制。

要打开语法打开补全: 
<code class="example">    setlocal omnifunc=syntaxcomplete#Complete</code>
<code class="example"></code>
你可以把下列语句放到  <a href="starting.html#.vimrc">.vimrc</a>  中 (要在任何 ":filetype" 命令之后)，使其自动生
效: 
<code class="example">    if has("autocmd") &amp;&amp; exists("+omnifunc")</code>
<code class="example">        autocmd Filetype *</code>
<code class="example">                    \   if &amp;omnifunc == "" |</code>
<code class="example">                    \           setlocal omnifunc=syntaxcomplete#Complete |</code>
<code class="example">                    \   endif</code>
<code class="example">    endif</code>
<code class="example"></code>
只有在针对特定文件类型的插件不存在的情况下，上述语句才对脚本设置补全操作。

每个文件类型可能有很多语法项目。此插件允许你定制从列表里包含或排除哪些语法组。
让我们看看 PHP 文件类型如何处理。

如果你正在编辑一个 index.php 文件，运行如下命令: 
<code class="example">    syntax list</code>
<code class="example"></code>
首先你将看到有许多不同的语法组。PHP 语言可以包含来自不同语言的元素，比如
HTML、 JavaScript 和许多其它语言。这种情况下，syntax 插件只包含由文件类型
"php" 开头的语法组。例如，缺省 PHP 包含这些语法组: phpEnvVar、phpIntVar、
phpFunctions。

如果希望包括非本文件类型指定的其他语法项目，可用正则表达式语法
(autoload/syntaxcomplete.vim 的 13.0 版本加入) 来加入项目。编辑 PHP 文件时查看
":syntax list" 的输出，我可以看到如下一些项目: 
<code class="example">    htmlArg,htmlTag,htmlTagName,javaScriptStatement,javaScriptGlobalObjects</code>
<code class="example"></code>
要在编辑 PHP 文件时时使用 Javascript 和 HTML 关键字语法高亮组，可以指定三个正
则表达式，每种语言分别一个。也可以简单限制包含组为特写值，而无需正则表达式: 
<code class="example">    let g:omni_syntax_group_include_php = 'php\w\+,javaScript\w\+,html\w\+'</code>
<code class="example">    let g:omni_syntax_group_include_php = 'phpFunctions,phpMethods'</code>

这个变量的基本形式是: 
<code class="example">    let g:omni_syntax_group_include_{filetype} = '逗号,分隔的,列表'</code>
<code class="example"></code>
PHP 语言可以进行语法高亮的项目非常多，而这些项目在全能补全列表里都会出现。

有些人可能觉得这个列表不实用或者只对某些项感兴趣。(如有必要) 有两种方法可以裁
剪这个列表。如果不想显示特定语法组，有两种不同的方法来标识这些组。第一个具体列
出这些语法组的名字。第二个使用正则表达式来指定所有想要的语法组。在 vimrc 中增
加两者之一即可: 
<code class="example">    let g:omni_syntax_group_exclude_php = 'phpCoreConstant,phpConstant'</code>
<code class="example">    let g:omni_syntax_group_exclude_php = 'php\w*Constant'</code>
<code class="example"></code>
该列表可以加入多个语法组，以逗号分隔。这个变量的基本形式是: 
<code class="example">    let g:omni_syntax_group_exclude_{filetype} = '逗号,分隔的,列表'</code>
<code class="example"></code>
可以建立任意多个这些变量，只要变量名尾部的文件类型不同就行了。

此插件使用 isKeyword 选项来决定用于语法项目的单词边界。例如，Scheme 语言的补全
应该包含 "-"，call-with-output-file。取决于你的文件类型，此方法未必能提供你期
待的单词。设置 g:omni_syntax_use_iskeyword 选项为 0 会强制语法插件在单词字符上
断开。在 vimrc 可以加如下行进行控制: 
<code class="example">    let g:omni_syntax_use_iskeyword = 0</code>
<code class="example"></code>
为了插件开发者着想，本插件提供了公共函数 OmniSyntaxList。本函数可用于提供语法
项目的列表。编辑 SQL 文件时 (:e syntax.sql)，可以用 ":syntax list" 命令看到各
种组和语法项目。示例: 
<code class="example">    syntax list</code>
<code class="example"></code>
返回的数据类似如此:
<code class="section">    sqlOperator    xxx some prior all like and any escape exists in is not </code>
<code class="section">                       or intersect minus between distinct </code>
<code class="section">                       links to Operator </code>
<code class="section">    sqlType        xxx varbit varchar nvarchar bigint int uniqueidentifier </code>
<code class="section">                       date money long tinyint unsigned xml text smalldate </code>
<code class="section">                       double datetime nchar smallint numeric time bit char </code>
<code class="section">                       varbinary binary smallmoney </code>
<code class="section">                       image float integer timestamp real decimal </code>

这里列出两个语法组: sqlOperator 和 sqlType。要得到语法项目的列表，可用几种不同
的方式调用 OminiSyntaxList。要得到不分组的所有语法项目: 
<code class="example">    echo OmniSyntaxList( [] )</code>
<code class="example"></code>
要得到 sqlOperator 语法组的所有语法项目: 
<code class="example">    echo OmniSyntaxList( ['sqlOperator'] )</code>
<code class="example"></code>
要得到 sqlOperator 和 sqlType 两个组的所有语法项目: 
<code class="example">    echo OmniSyntaxList( ['sqlOperator', 'sqlType'] )</code>
<code class="example"></code>
也可用正则表达式: 
<code class="example">    echo OmniSyntaxList( ['sql\w\+'] )</code>
<code class="example"></code>
在插件中，通常可以把输出结果赋给一个列表: 
<code class="example">    let myKeywords = []</code>
<code class="example">    let myKeywords = OmniSyntaxList( ['sqlKeyword'] )</code>
<code class="example"></code>
<code class="example"></code>
<code class="example"></code>
SQL                                                     <b class="vimtag"> <a name="ft-sql-omni">ft-sql-omni</a> </b>

SQL 语言的补全包括语句、函数和关键字。还可以动态地补全表、过程、视图和列的列
表，此时数据直接从数据库里提取。详细的指令和教程见  <a href="ft_sql.html#omni-sql-completion">omni-sql-completion</a> 。

SQL 补全插件可以和其它补全插件一起使用。例如，PHP 文件类型有它自己的补全插件。
因为 PHP 常用来生成访问数据库的动态网站，也可以同时打开 SQL 补全插件。这样就可
以同时补全 PHP 代码和 SQL 代码。


XML                                                     <b class="vimtag"> <a name="ft-xml-omni">ft-xml-omni</a> </b>

Vim 7 为 XML 文件中提供上下文相关的补全机制。它依赖于特殊的数据文件
 <a href="insert.html#xml-omni-datafile">xml-omni-datafile</a>  和两个命令:  <a href="insert.html#:XMLns">:XMLns</a>  和  <a href="insert.html#:XMLent">:XMLent</a> 。特性如下:

- "&lt;" 之后，根据上下文补全标签名
- 标签内部补全合适的属性
- 如果属性只有有限的几个可能值，用它们来补全
- 补全实体 (entity) 名 ( <a href="insert.html#xml-omni-datafile">xml-omni-datafile</a>  里的定义加上当前文件 "&lt;!ENTITY" 的
  声明)
- "&lt;/" 之后，<code class="keystroke">CTRL-X</code> <code class="keystroke">CTRL-O</code> 会关闭最后打开的标签

XML 数据文件的格式                                      <b class="vimtag"> <a name="xml-omni-datafile">xml-omni-datafile</a> </b>

XML 数据文件保存在 <a href="options.html#'runtimepath'">'runtimepath'</a> 下的 "autoload/xml" 目录中。Vim 发布在
"$VIMRUNTIME/autoload/xml" 目录下提供了示例数据文件。这些文件名有特别含义，命
令里使用会使用这些名字。文件名应该唯一，否则以后会产生冲突。例如，xhtml10s.vim
代表 XHTML 1.0 Strict 标准的数据文件。

每个文件包含一个名字形如 g:xmldata_xhtml10s 的变量。它由两个部分组成:

1. "g:xmldata_"  通用前缀，所有数据文件都是如此
2. "xhtml10s"    文件名，描述 XML 的方言；会用作  <a href="insert.html#:XMLns">:XMLns</a>  命令的参数

第二部分必须和文件名完全一样。

该变量为字典  <a href="eval.html#Dictionary">Dictionary</a>  类型。键是标签名，而值是两个元素的  <a href="eval.html#List">List</a> 。列表中第
一个元素也是列表，包含可能的子元素名称，第二个元素是字典  <a href="eval.html#Dictionary">Dictionary</a> ，键是属
性名，而值是属性的可能值。例如: 
<code class="example"></code>
<code class="example">    let g:xmldata_crippled = {</code>
<code class="example">    \ "vimxmlentities": ["amp", "lt", "gt", "apos", "quot"],</code>
<code class="example">    \ 'vimxmlroot': ['tag1'],</code>
<code class="example">    \ 'tag1':</code>
<code class="example">    \ [ ['childoftag1a', 'childoftag1b'], {'attroftag1a': [],</code>
<code class="example">    \ 'attroftag1b': ['valueofattr1', 'valueofattr2']}],</code>
<code class="example">    \ 'childoftag1a':</code>
<code class="example">    \ [ [], {'attrofchild': ['attrofchild']}],</code>
<code class="example">    \ 'childoftag1b':</code>
<code class="example">    \ [ ['childoftag1a'], {'attrofchild': []}],</code>
<code class="example">    \ "vimxmltaginfo": {</code>
<code class="example">    \ 'tag1': ['Menu info', 'Long information visible in preview window']},</code>
<code class="example">    \ 'vimxmlattrinfo': {</code>
<code class="example">    \ 'attrofchild': ['Menu info', 'Long information visible in preview window']}}</code>
<code class="example"></code>
该例应放到 "autoload/xml/crippled.vim" 文件中。可用于编写下述文件: 
<code class="example"></code>
<code class="example">    &lt;tag1 attroftag1b="valueofattr1"&gt;</code>
<code class="example">        &lt;childoftag1a attrofchild&gt;</code>
<code class="example">                &amp;amp; &amp;lt;</code>
<code class="example">        &lt;/childoftag1a&gt;</code>
<code class="example">        &lt;childoftag1b attrofchild="5"&gt;</code>
<code class="example">            &lt;childoftag1a&gt;</code>
<code class="example">                &amp;gt; &amp;apos; &amp;quot;</code>
<code class="example">            &lt;/childoftag1a&gt;</code>
<code class="example">        &lt;/childoftag1b&gt;</code>
<code class="example">    &lt;/tag1&gt;</code>
<code class="example"></code>
从该例中，我们可以看到四种特殊元素:

1. "vimxmlentities" - 特殊键，包含此 XML 方言的所有实体的列表。
2. 如果这个包含属性可能值的列表只有一个元素，而该元素和属性名一样，那么该属性
   被看作逻辑值，插入时使用 <code class="badlink">'attrname'</code> 而不是 'attrname="'。
3. "vimxmltaginfo" - 特殊键，包含键为标签名、值为两元素列表的字典。值列表包含
   附加的菜单信息和长描述。
4. "vimxmlattrinfo" - 特殊键，包含键为属性名、值为两元素列表的字典。值列表包含
   附加的菜单信息和长描述。

<code class="note">注意</code>: 数据文件里的标签名 <code class="emphasis">必须</code> 不能包含命名空间的描述。示例见 xsl.vim。
<code class="note">注意</code>: 所有的数据和函数都作为全局变量/函数可以在任何地方访问，所以它们可以用于
个人编辑用的函数。


DTD -&gt; Vim                                                      <b class="vimtag"> <a name="dtd2vim">dtd2vim</a> </b>

 <a href="intro.html#www">www</a>  上有个脚本  <a href="insert.html#dtd2vim">dtd2vim</a> ，能够解析 DTD 并为 Vim XML 全能补全建立 XML 数据文
件。

    dtd2vim: <a href="http://www.vim.org/scripts/script.php?script_id=1462">http://www.vim.org/scripts/script.php?script_id=1462</a>

查看文件开始部分的详细用例。
该脚本需要 Perl 和:

    perlSGML: <a href="http://savannah.nongnu.org/projects/perlsgml">http://savannah.nongnu.org/projects/perlsgml</a>


命令

:XMLns <code class="special">{name}</code> [<code class="special">{namespace}</code>]                                     <b class="vimtag"> <a name=":XMLns">:XMLns</a> </b>

Vim 需要知道要使用的数据文件和命名空间。 <a href="insert.html#:XMLns">:XMLns</a>  命令可以载入数据文件并把数据
连接到合适的命名空间。第一个 (必需的) 参数是数据名 (xhtml10s、xsl)。第二个参数
是命名空间编码 (h，xsl)。如果不使用第二个参数，那么将使用默认值--不声明命名空
间。例如在 .xsl 文件中使用 XML 补全: 
<code class="example"></code>
<code class="example">        :XMLns xhtml10s</code>
<code class="example">        :XMLns xsl xsl</code>
<code class="example"></code>
<code class="example"></code>
:XMLent <code class="special">{name}</code>                                                  <b class="vimtag"> <a name=":XMLent">:XMLent</a> </b>

缺省，根据默认命名空间的数据文件补全实体 (entity) 。如果没有默认命名空间，应该
用 XMLent 命令: 
<code class="example"></code>
<code class="example">        :XMLent xhtml10s</code>
<code class="example"></code>
用法

在下述情况下 (在前一部分的声明之后，| 代表当前光标位置): 
<code class="example"></code>
<code class="example">        &lt;|</code>
<code class="example"></code>
补全合适的 XHTML 标签。而: 
<code class="example"></code>
<code class="example">        &lt;xsl:|</code>
<code class="example"></code>
补全合适的 XSL 标签。


由  <a href="userfunc.html#autoload">autoload</a>  机制提供的 xmlcomplete.vim 脚本定义了函数
xmlcomplete#GetLastOpenTag()，在 XML 文件中，这个函数可用于取得最后打开的标签
名 (下例必须先定义 b:unaryTagsStack): 
<code class="example"></code>
<code class="example">        :echo xmlcomplete#GetLastOpenTag("b:unaryTagsStack")</code>
<code class="example"></code>
<code class="example"></code>
<code class="example"></code>
<code class="example"></code>
<code class="example"></code>
</section><hr class="doubleline" /><section class=inner>
<h4>8. 插入模式命令                                         <b class="vimtag"> <a name="inserting">inserting</a> </b></h4>
下列命令可以用来在缓冲区里插入新的文本。它们都可以撤销，也可以通过 "." 命令重
复。

                                                        <b class="vimtag"> <a name="a">a</a> </b>
a                       在光标后附加文本 <code class="special">[count]</code> 次。如果光标在空行的第一列，
                        启动插入模式。但在置位了 <a href="options.html#'virtualedit'">'virtualedit'</a> 以后就不是！

                                                        <b class="vimtag"> <a name="A">A</a> </b>
A                       在行尾附加文本 <code class="special">[count]</code> 次。
                        可在可视列块中用 "A"，参见  <a href="visual.html#v_b_A">v_b_A</a> 。

<code class="special">&lt;insert&gt;</code>        或                              <b class="vimtag"> <a name="i">i</a> </b> <b class="vimtag"> <a name="insert">insert</a> </b> <b class="vimtag"> <a name="%3CInsert%3E">&lt;Insert&gt;</a> </b>
i                       在光标前插入文本 <code class="special">[count]</code> 次。在插入模式里使用 <code class="keystroke">CTRL-O</code>
                        的时候， <a href="insert.html#i_CTRL-O">i_CTRL-O</a>  不支持计数。

                                                        <b class="vimtag"> <a name="I">I</a> </b>
I                       在本行第一个非空白字符之前插入文本 <code class="special">[count]</code> 次。
                        如果 <a href="options.html#'cpoptions'">'cpoptions'</a> 里有 'H' 标志位而本行只有空白，在最后
                        一个空白前插入。
                        可在可视列块中用 "I"，参见  <a href="visual.html#v_b_I">v_b_I</a> 。

                                                        <b class="vimtag"> <a name="gI">gI</a> </b>
gI                      在第一列插入文本 <code class="special">[count]</code> 次。

                                                        <b class="vimtag"> <a name="gi">gi</a> </b>
gi                      在当前缓冲区最近一次插入模式停止的位置继续插入文本。
                        该位置记在  <a href="motion.html#'^">'^</a>  位置标记里。如果标记在行末之后，和
                        "`^i" 有所差异。
                        该位置在插入/删除行时会自动修正。但 <code class="emphasis">不</code> 在插入/删除字符
                        时被修正。
                        使用  <a href="motion.html#:keepjumps">:keepjumps</a>  命令修饰符时，不改变  <a href="motion.html#'^">'^</a>  位置标记。

                                                        <b class="vimtag"> <a name="o">o</a> </b>
o                       在光标下方开启新行，并插入文本，重复 <code class="special">[count]</code> 次。
                        如果 <a href="options.html#'cpoptions'">'cpoptions'</a> 里有 '#' 标志位，忽略计数。

                                                        <b class="vimtag"> <a name="O">O</a> </b>
O                       在光标上方开启新行，并插入文本，重复 <code class="special">[count]</code> 次。
                        如果 <a href="options.html#'cpoptions'">'cpoptions'</a> 里有 '#' 标志位，忽略计数。

这些命令用以开始插入文本。你可以用 <code class="special">&lt;Esc&gt;</code> 退出插入模式。关于插入模式里的其它特
殊字符，见  <a href="insert.html#mode-ins-repl">mode-ins-repl</a> 。<code class="special">[count]</code> 的效果只有在退出插入模式以后才会发生。

如果打开 <a href="options.html#'autoindent'">'autoindent'</a>，新行的缩进从上一行得到。打开 <a href="options.html#'smartindent'">'smartindent'</a> 或 <a href="options.html#'cindent'">'cindent'</a>
时，行的缩进根据 C 程序的要求自动调整。

可设置 <a href="options.html#'formatoptions'">'formatoptions'</a>，开启新行时自动复制注释头部。

<a href="options.html#'textwidth'">'textwidth'</a> 可以设置一行的最大宽度。如果一行过长，在添加字符时会自动添加换行
符。


</section><hr class="doubleline" /><section class=inner>
<h4>9. Ex 插入命令                                          <b class="vimtag"> <a name="inserting-ex">inserting-ex</a> </b></h4>
                                                        <b class="vimtag"> <a name=":a">:a</a> </b> <b class="vimtag"> <a name=":append">:append</a> </b>
:<code class="special">{range}</code>a[ppend][!]     在指定行下方添加若干行。如果没有给出 <code class="special">{range}</code>，文本会在
                        当前行之后插入。
                        加入 [!] 切换此命令执行时的 <a href="options.html#'autoindent'">'autoindent'</a>。
                        此命令在  <a href="vim9.html#Vim9">Vim9</a>  脚本里不支持，因为它太容易和变量名混淆
                        了。

                                                        <b class="vimtag"> <a name=":i">:i</a> </b> <b class="vimtag"> <a name=":in">:in</a> </b> <b class="vimtag"> <a name=":insert">:insert</a> </b>
:<code class="special">{range}</code>i[nsert][!]     在指定行上方添加若干行。如果没有给出 <code class="special">{range}</code>，文本会在
                        当前行之前插入。
                        加入 [!] 切换此命令执行时的 <a href="options.html#'autoindent'">'autoindent'</a>。
                        此命令在  <a href="vim9.html#Vim9">Vim9</a>  脚本里不支持，因为它太容易和变量名混淆
                        了。

这两个命令会继续要求行，直到你输入了只包含 "." 的一行。小心反斜杠开始的行，见
 <a href="repeat.html#line-continuation">line-continuation</a> 。

Ex 模式 (见  <a href="starting.html#-e">-e</a> ) 下，行尾的反斜杠可用来插入 NUL 字符。所以要使一行以反斜杠结
尾，用两个反斜杠。也就是说仅在行尾情况下，反斜杠数目减半。

<code class="note">注意</code>: 这些命令不能和  <a href="repeat.html#:global">:global</a>  或  <a href="repeat.html#:vglobal">:vglobal</a>  一起使用。":append" 和 ":insert"
在 ":if" 和 ":endif"、":for" 和 ":endfor" 还有 ":while" 和 ":endwhile" 之间不
能很好的工作。

                                                        <b class="vimtag"> <a name=":start">:start</a> </b> <b class="vimtag"> <a name=":startinsert">:startinsert</a> </b>
:star[tinsert][!]       在执行完本命令后，启动插入模式。和普通模式下输入 "i"
                        类似。如果包含 !，和 "A" 类似，附加到行后。否则，就从
                        光标当前位置开始插入。
                        <code class="note">注意</code> 在函数或者脚本里使用本命令时，插入只会在函数和脚
                        本结束的时候才会开始。
                        此命令不能在  <a href="various.html#:normal">:normal</a>  里使用。

                                                        <b class="vimtag"> <a name=":stopi">:stopi</a> </b> <b class="vimtag"> <a name=":stopinsert">:stopinsert</a> </b>
:stopi[nsert]           尽快停止插入模式。和在插入模式时输入 <code class="special">&lt;Esc&gt;</code> 类似。可以
                        用在自动命令里。示例: 
<code class="example">                                :au BufEnter scratch stopinsert</code>

                                        <b class="vimtag"> <a name="replacing-ex">replacing-ex</a> </b> <b class="vimtag"> <a name=":startreplace">:startreplace</a> </b>
:startr[eplace][!]      在执行完本命令后，启动替换模式。和普通模式下输入 "R"
                        类似。如果包含 !，和 "$R" 类似 (也就是，从行尾开始替换
                        模式)。否则，从光标当前位置开始替换。
                        <code class="note">注意</code> 在函数或者脚本里使用本命令时，替换只会在函数和脚
                        本结束的时候才会开始。

                                                        <b class="vimtag"> <a name=":startgreplace">:startgreplace</a> </b>
:startg[replace][!]     和  <a href="insert.html#:startreplace">:startreplace</a>  完全类似，用虚拟替换模式，和使用
                         <a href="change.html#gR">gR</a>  类似。

</section><hr class="doubleline" /><section class=inner>
<h4>10. 插入文件                                            <b class="vimtag"> <a name="inserting-file">inserting-file</a> </b></h4>
                                                        <b class="vimtag"> <a name=":r">:r</a> </b> <b class="vimtag"> <a name=":re">:re</a> </b> <b class="vimtag"> <a name=":read">:read</a> </b>
:r[ead] <code class="special">[++opt]</code> <code class="special">[name]</code>
                        在光标下方插入文件 <code class="special">[name]</code> (缺省: 当前文件)。
                         <a href="editing.html#++opt">++opt</a>  说明 <code class="special">[++opt]</code> 可能的取值。

:<code class="special">{range}</code>r[ead] <code class="special">[++opt]</code> <code class="special">[name]</code>
                        在指定行下方插入文件 <code class="special">[name]</code> (缺省: 当前文件)。
                         <a href="editing.html#++opt">++opt</a>  说明 <code class="special">[++opt]</code> 可能的取值。

                                                        <b class="vimtag"> <a name=":r!">:r!</a> </b> <b class="vimtag"> <a name=":read!">:read!</a> </b>
:<code class="special">[range]</code>r[ead] <code class="special">[++opt]</code> !<code class="special">{cmd}</code>
                        执行 <code class="special">{cmd}</code> 并把它的标准输出插入到光标下方。临时文件会
                        建立来保存命令输出的结果，并被读到缓冲区里。
                        <a href="options.html#'shellredir'">'shellredir'</a> 用来保存命令的输出结果，它可以设置是否包
                        含标准错误的输出。<code class="special">{cmd}</code> 的执行和 ":!<code class="special">{cmd}</code>" 类似，任何
                        的 '!' 会被替换成以前的命令  <a href="various.html#:!">:!</a> 。
                         <a href="editing.html#++opt">++opt</a>  说明 <code class="special">[++opt]</code> 可能的取值。

这些命令插入文件的内容，或者命令的输出结果到缓冲区里。两者都可以撤销。但不能用
"." 命令重复。它们是基于行工作的，插入从光标所在行或指定行的下方开始。要在第一
行之上插入文本，使用命令 ":0r <code class="special">{name}</code>"。

在 ":read" 命令之后，光标留在第一个新行的第一个非空白处。和 Ex 模式不一样。那
里光标留在最后一个新行上 (对不起，那是为了和 Vi 兼容)。

如果文件名字通过 ":r" 给出，它成为轮换文件。这可以用来，比如说，你想编辑那个文
件的时候: ":e! #"。该特性可以通过删除 <a href="options.html#'cpoptions'">'cpoptions'</a> 选项里的 'a' 标志位来关闭。

<code class="special">[++opt]</code> 参数里，有一个是 ":read" 专用的: ++edit 参数。当 ":read" 命令就像编辑
文件一样把文件读入到缓冲区时，这个参数很有用。在空缓冲区上使用如下命令: 
<code class="example">        :read ++edit filename</code>
效果是 <a href="options.html#'fileformat'">'fileformat'</a>、<a href="options.html#'fileencoding'">'fileencoding'</a>、<a href="options.html#'bomb'">'bomb'</a> 等选项根据 "filename" 的检测进行设
置。<code class="note">注意</code> 会留下一行空行，你也许想把它删掉。

                                                        <b class="vimtag"> <a name="file-read">file-read</a> </b>
<a href="options.html#'fileformat'">'fileformat'</a> 选项设置文件的 <code class="special">&lt;EOL&gt;</code> 风格:
<code class="section"><a href="options.html#'fileformat'">'fileformat'</a>    字符               名称                         </code>
  "dos"         <code class="special">&lt;CR&gt;</code><code class="special">&lt;NL&gt;</code> 或 <code class="special">&lt;NL&gt;</code>   DOS 格式
  "unix"        <code class="special">&lt;NL&gt;</code>               Unix 格式
  "mac"         <code class="special">&lt;CR&gt;</code>               Mac 格式
以前使用 <a href="options.html#'textmode'">'textmode'</a>。现在已经废弃了。

如果 <a href="options.html#'fileformat'">'fileformat'</a> 为 "dos"，在 <code class="special">&lt;NL&gt;</code> 之前的 <code class="special">&lt;CR&gt;</code> 被忽略，而在文件尾部的 <code class="keystroke">CTRL-Z</code>
被忽略。

如果 <a href="options.html#'fileformat'">'fileformat'</a> 为 "mac"，文件里的 <code class="special">&lt;NL&gt;</code> 被内部表示为 <code class="special">&lt;CR&gt;</code>。这是为了避免和用
来表示 <code class="special">&lt;NUL&gt;</code> 的 <code class="special">&lt;NL&gt;</code> 引起混淆。见  <a href="pattern.html#CR-used-for-NL">CR-used-for-NL</a> 。

如果 <a href="options.html#'fileformats'">'fileformats'</a> 选项不为空，Vim 试图识别 <code class="special">&lt;EOL&gt;</code> 的类型 (见  <a href="editing.html#file-formats">file-formats</a> )。
不过，<a href="options.html#'fileformat'">'fileformat'</a> 选项的值不会被改变，检测到的格式只会在读入文件时使用。
<a href="options.html#'fileencodings'">'fileencodings'</a> 与此情形类似。

非 Win32 系统上，读入 DOS 格式的文件时给出消息 "[dos format]"，以提醒你发生了
不寻常的事情。
Macintosh 和 Win32 系统上，读入 Unix 格式的文件时给出消息 "[unix format]"。
非 Macintosh 的系统上，读入 Mac 格式的文件时给出消息 "[mac format]"。

关于如何使用 ":r !" 的一个例子: 
<code class="example">        :r !uuencode binfile binfile</code>
该命令读入 "binfile"，用 uuencode 进行编码，并读入当前缓冲区。可以用于编辑包含
附带的二进制的文件的 e-mail。

                                                        <b class="vimtag"> <a name="read-messages">read-messages</a> </b>
在读入文件时，Vim 会显示消息，显示读入文件的相关信息。以下的表格给出一些项目的
解释。其它的项目都不言自明。使用长格式还是短格式取决于 <a href="options.html#'shortmess'">'shortmess'</a> 选项的设
置。

<code class="section">        长              短              含义 </code>
        <code class="special">[readonly]</code>      <code class="special">{RO}</code>            文件被写保护
        [fifo/socket]                   使用流
        <code class="special">[fifo]</code>                          使用 fifo 流
        <code class="special">[socket]</code>                        使用套接字 (socket) 流
        [CR missing]                    使用 "dos" <a href="options.html#'fileformat'">'fileformat'</a> 读入文件的时候
                                        出现没有前导的 CR 的 NL
        [NL found]                      使用 "mac" <a href="options.html#'fileformat'">'fileformat'</a> 读入文件的时候
                                        出现 NL (可能是 "unix" 格式)
        [long lines split]              至少一行以上被分割
        [NOT converted]                 期待从 <a href="options.html#'fileencoding'">'fileencoding'</a> 到 <a href="options.html#'encoding'">'encoding'</a> 的
                                        转换但是做不到
        <code class="special">[converted]</code>                     从 <a href="options.html#'fileencoding'">'fileencoding'</a> 到 <a href="options.html#'encoding'">'encoding'</a> 的转换
                                        完成
        <code class="special">[crypted]</code>                       文件被解密
        [READ ERRORS]                   不是文件所有部分都被成功读入


 vim:tw=78:ts=8:noet:ft=help:norl:
</section>
</article>
<footer>
Generated by vim2html
</footer>
</body>
</html>
